On September, Atalanta and Hellas Verona had agreed for the signature of Bonaventura and Verona’s ex sporting director, Sogliano, had talked to Giacomo but in the last hours of the Italian transfer window, Milan announced the signature of Bonaventura from Atalanta for a fee reported to be around €7 million after they failed to sign Jonathan Biabiany. His agent later revealed that Bonaventura cried after signing for Milan as his dream became true. He was given the number 28, which was previously worn by Urby Emanuelson. On 14 September, Giacomo Bonaventura scored a goal on his debut as Milan beat Parma 5–4. Bonaventura scored his second goal for Milan on 29 October against Cagliari and was voted man of the match. On 12 December, Bonaventura scored a powerful header and assisted Jérémy Ménez’s goal as Milan defeated Napoli 2–0; Bonaventura was also voted man of the match against Napoli and again in the next week against Roma. The following match against Sassuolo, he scored a goal and later in the match he received a second yellow card and was sent off. It was the first time in his career that he was sent off. On 30 May, he scored twice against his former team Atalanta in a 3–1 victory. Bonaventura finished his first season at Milan with 7 goals and 4 assists in all competitions.
On 23 August 2015, Bonaventura made his season debut as Milan lost 2–0 to Fiorentina. The following match against Empoli, Bonaventura came on the pitch as the substitute for Suso in the 55th minute and managed to assist Luiz Adriano’s winning goal from a corner kick 15 minutes later. On 19 September, Giacomo Bonaventura assisted Carlos Bacca’s first goal and scored directly from a free-kick in a 3–2 win over Palermo. He also gained another assist and goal in Milan’s next game, the 2–3 win over Udinese. Once again, he assisted both Carlos Bacca’s and Philippe Mexès’ goals against Lazio in the 3–1 away win on 1 November. He continued to perform well under the team’s coach Siniša Mihajlović and became a fundamental player for his team throughout the season. After missing a 0–0 draw against his former team Atalanta through suspension, he scored the opener in a 4–1 defeat of Sampdoria on 28 November. He scored again in his next game on 1 December, a 3–1 Coppa Italia defeat of Crotone, via a brilliant 20-yard free kick. On 20 December he assisted Carlos Bacca’s goal and scored a late goal as Milan beat Frosinone 4–2. On 17 January 2016, he provided another assist for Carlos Bacca as the Rossoneri beat Fiorentina 2–0. He ended the season with 7 goals and 8 assists in all competitions as Milan finished 7th in Serie A, lost the Coppa Italia final against Juventus at extra time.
Giacomo Bonaventura playing for Milan against Bayern Munich in pre-season.
At the beginning of the season, Giacomo Bonaventura switched his number from 28 to 5. He started Milan’s opening match of the Serie A season against Torino. In the second half of the match, he was fouled inside the six-yard box by Joel Obi and Milan was given a penalty which was converted by Carlos Bacca to complete his hat-trick in Milan’s 3–2 win. He scored his first goal of the season on 2 October in Milan’s memorable comeback against Sassuolo as the game finished 4–3. The following week he assisted M’Baye Niang’s goal against ChievoVerona in a 3–1 win. He also assisted Suso’s first goal in the 2–2 draw against city rivals, Inter. On 23 December 2016, Bonaventura scored the equalising goal in the Supercoppa Italiana against Juventus; he later netted his penalty in the resulting shoot-out, helping Milan to a 4–3 victory. He signed a contract extension through 2020 with Milan on 18 January 2017. On 29 January, Bonaventura suffered an injury in a match against Udinese which ruled him out for the rest of the season following surgery on a thigh injury; earlier in that match, he scored Milan’s goal in the 2–1 loss. He returned to the squad for the last game of the season against Cagliari on 28 May, but couldn’t make an appearance during the match as Milan lost 2–1. He ended the season with 5 goals and 4 assists in 22 appearances in all competition as Milan finished 6th in Serie A, was knocked out of Coppa Italia in Quarter-finals by Juventus and won the Supercoppa Italiana.
Bonaventura played his first game in Europe in a 1–0 win against CS U Craiova in the first leg of Milan’s Europa League qualification match on 27 July 2017. He also featured in the second leg the following week, in which he scored the first goal in their 2–0 win. It was his first goal in a European competition and he was voted Man of the Match thereafter for his performance. On 17 August, he got a late injury in Milan’s Europa league playoff match against Shkëndija. On 14 September 2017, Giacomo Bonaventura made his 100th Milan appearance, in a 5–1 away win against FK Austria Wien. His first goal of the season in Serie A against Benevento on 3 December. The following week he scored a brace in a 2–1 win against Bologna. On 6 January 2018, he made his 100th appearance in Serie A for Milan in a 1-0 win against Crotone. He played his 200th match in Serie A on in the 2–1 victory over Cagliari on 21 January 2018.
In October 2018, Bonaventura suffered a knee injury that was expected to keep him out of play for nine months.
Right now it is expected that Giacomo Bonaventura will be ready to play on the start of the season 2019/2020.