Pierre Kalulu’s cross was deflected into the net after an early Porto strike, as Milan picked up their first Champions League point, but it was another far from vintage performance.
The Rossoneri had lost all three Champions League games and needed a victory to avoid crashing out already. Brahim Diaz returned after contracting COVID, but Fode Ballo-Toure joined Mike Maignan, Ante Rebic, Alessio Romagnoli, Junior Messias and Alessandro Plizzari on the treatment table. Porto won 1-0 at home, but missed Wendell and Ivan Marcano, losing Matheus Uribe in the warm-up to be replaced by Marko Grujic.
It was a nightmare start for Milan, as Grujic robbed Ismael Bennacer and set up Luis Diaz, who had time to take a touch and beat the on-rushing Ciprian Tatarusanu from eight yards.
Tatarusanu prevented a second goal, getting his fingertips to the Grujic header on a free kick and pushing it past the far post.
The goalkeeper also got his hand to another Grujic header on a corner, while Milan’s first chance was a sudden Olivier Giroud curler out of nowhere that was fingertipped over the bar by Diogo Costa.
Theo Hernandez went on the counter from his own half, but Alexis Saelemaekers then ballooned his finish into the sky from a Rafael Leao pass.
Davide Calabria went off injured at half-time and Evanilson almost doubled Porto’s lead, his header bouncing off the top of the crossbar.
Milan finally got an equaliser when a free kick was deflected into the path of Giroud, he forced a save on the turn and Pierre Kalulu tried to roll across for a tap-in, which came accidentally from Chancel Mbemba.
The goal seemed to wake the Diavolo and their fans up, Tonali firing a free kick over and substitute Zlatan Ibrahimovic just unable to reach the Leao pass before the goalkeeper.
Ibrahimovic had the ball in the net on 83 minutes, but Theo Hernandez was already offside when providing the assist.
Theo Hernandez’s slide-rule pass was crucially intercepted by Pepe before Ibrahimovic could pounce.
Milan 1-1 Porto
Luis Diaz 6 (P), Mbemba og 61 (M)