João Pedro joined the youth ranks of Atlético Mineiro in April 2006, and made his competitive first team debut on 23 May 2010 in a game against Atlético Paranaense. His successive good performances then led head coachVanderlei Luxemburgo to regularly select him for the Brazilian league games held between May and August 2010, also switching him from his original position of second striker to an attacking midfielder role.
On 30 August 2010, Serie A club Palermo announced the signing of João Pedro on a five-year contract. He made his debut in the final minutes of a 2010–11 UEFA Europa League game against Sparta Prague. His Serie A debut came on 17 January 2011, as a second-half substitute for Josip Iličić in a 1–3 loss to Cagliari. On 29 January 2011, Vitória Guimarães announced the signing of João Pedro on loan for the remainder of the season. He was sent back on 4 April for disciplinary reasons, after reacting angrily to being substituted in the first half against Sporting CP. On 19 August 2011, Palermo loaned João Pedro to Uruguayan club Peñarol.
Santos / Estoril
João Pedro returned to his homeland on 5 July2012, signing with Santos until 2014. The club purchased 20% of his economic rights from Traffic Sports Marketing, and had priority to buy 30% more. On 1 July 2013, after not featuring with the first team in 2013 season, João Pedro rescinded with Santos and signed a one-year deal with Estoril Praia. He scored eight times in his only full season for the Lisbon District club as they came fourth, including two on 1 March 2014 in a 4–0 home win over S.C. Olhanense.
Cagliari
João Pedro returned to Serie A on 30 August 2014, signing for Cagliari for around €1 million and exchange with Matías Cabrera. The team suffered relegation in his first season, but he scored 13 times in 38 games as they won the 2015–16 Serie B, including a hat-trick in a 6–0 home win over Brescia on 16 April. In August 2017, João Pedro signed a new contract to last until 2021. The following 16 May, he was given a six-month ban after testing positive for banned diuretic hydrochlorothiazide following a match against Sassuolo in February. João Pedro signed a new contract in November 2018, to last until 2022. On 21 December 2019 he scored in a 2–1 loss at Udinese to reach 50 for the Sardinians, seventh in their all-time scorers.