Milan had several chances when Mario Balotelli came on, but were beaten 3-1 in Barcelona by a Leo Messi brace.
Elsewhere, Ajax beat Celtic 1-0, so the Rossoneri should qualify if they win just one of the remaining two matches.
Max Allegri sensationally dropped Balotelli to the bench, favouring Kaka behind Robinho as a ‘False 9.’ Stephan El Shaarawy, Giampaolo Pazzini, Antonio Nocerino, Mattia De Sciglio, Marco Amelia, Matias Silvestre and the cup-tied Gabriel and M’Baye Niang were out, but Christian Abbiati returned in goal. Barca were without Jordi Alba, Ibrahim Afellay, Cuenca and Dos Santos, but Adriano recovered ahead of schedule.
The Rossoneri have faced Barcelona repeatedly in recent years, but their last win at Camp Nou was in 2000. As expected, they sat back eager to hit on the counter and allowed the hosts plenty of possession.
An Adriano ball flashed all the way across the face of goal and Alexis Sanchez just failed to get the final touch from a couple of yards. Moments later, the ex-Udinese man nodded on to the side-netting, as Barca’s pressure went all the way to the goal.
The referee pointed to the spot when Neymar went down under the slightest nudge from Ignazio Abate. Leo Messi, who had not scored in four Liga games, converted a powerful penalty.
Riccardo Montolivo had the first Milan chance on 35 minutes, gathering from Andrea Poli to curl just past the far post.
Philippe Mexes needed practically a goalline clearance after Messi had chipped Abbiati, but Barcelona doubled their lead.
A Xavi Hernandez free kick was floated in for the glancing header of Sergio Busquets, though there were suspicions of offside. It was yet another goal conceded from a set play and in the air for the Rossoneri.
Milan were able to pull one back on the stroke of half-time with a bit of luck. Kaka burst down the left and pulled back from the by-line, but Gerard Pique accidentally poked it past his own goalkeeper at the near post.
Balotelli replaced Robinho for the second half and within four minutes Javier Mascherano had to intercept a dangerous Kaka assist that would’ve sent him clear. Moments later SuperMario tested Victor Valdes at the near post with an angled drive.
The Spaniards thought they had scored a third goal, but Messi was offside when deflecting Adriano’s effort into the far top corner. Neymar was incorrectly flagged offside when going clear, as Urby Emanuelson was keeping everyone level.
Abbiati flew to palm an Andres Iniesta strike round the far post, but Balotelli dribbled past two players down the right and Kaka finished the move wide from six yards under pressure from Dani Alves.
Adriano blasted over from a corner and Nigel De Jong blocked Neymar’s attempt, while the Brazilian striker’s finish did not live up to the mazy run. Abbiati performed a stunning reaction save when one-on-one with Alexis Sanchez, but Valdes had to hoof clear when Montolivo’s inspired pass was finding Sulley Muntari.
Barcelona finally put the game beyond Milan’s reach when Messi combined with Cesc Fabregas to burst through the middle of the defence and beat Abbiati.
Mexes needed a last-ditch tackle to stop Messi when clear on goal.
Barcelona 3-1 Milan
Scorers: Messi pen 30, 83 (B), Busquets 40 (B), Pique og 45 (M)
Barcelona: Valdes; Dani Alves, Piqué, Mascherano, Adriano; Xavi (Song 88), Busquets, Iniesta (Fabregas 78); Alexis Sanchez, Messi, Neymar (Pedro 85)
Milan: Abbiati; Abate, Mexes, Zapata, Emanuelson; Poli (Birsa 74), Montolivo, De Jong, Muntari; Kaka (Matri 84); Robinho (Balotelli 46)
Ref: Mazic (SRB)
Tickets for the Champions League final between Juventus and Real Madrid are still on sale with reseller Viagogo - Click to find out more