The visitors, who have yet to lose this season, twice led thanks to goals from Mattia Destro and a Kevin Strootman penalty but Milan showed great character to respond with strikes from Cristian Zapata and Sulley Muntari.
The result means that Roma are five points behind Juventus and have now only won one in their last six whilst Milan move up a place to 11th above Cagliari despite winning only once in their last eight.
Many expected the returning Francesco Totti to start the match but it was Destro who was preferred up front.
And Rudi Garcia’s decision to rest the talismanic striker, who has notched five goals against Milan in the San Siro appeared justified when Destro opened the scoring.
A tidy sequence of Roma passing led to the goal as the excellent Strootman crossed for Destro to slot past Christian Abbiati from a yard out for his second of the season.
Roma continued to dominate possession but were rocked when Milan drew level courtesy of Zapata, the left back ghosting to the back post to knock in Muntari’s flick-on direct from the corner.
Michael Bradley looked to have restored Roma’s lead as he flicked the ball goalwards on the back post, only for Daniele Bonera to hook the ball off the line.
The visitors continued to press forward and Gervinho squandered an excellent chance when set through on goal down the left but his second touch let him down, allowing Zapata to get back and make the challenge with Destro screaming for the ball in the centre.
Massimiliano Allegri made a change in goal at the break, bringing on Gabriel for Christian Abbiati. But the change backfired almost immediately as the substitute keeper rushed off his line to bring down Gervinho for a penalty and a yellow card.
Strootman did the rest from the spot and it looked as if Roma would then grab the game by the scruff of the neck, Gervinho exchanging passes with Adem Ljajic before being denied by an excellent Urby Emanuelson challenge.
Michael Bradley squandered an excellent chance to put Roma further ahead but planted his header wide and moments later, Milan were level as the previously quiet Mario Balotelli laid his pass off to Muntari to smash home his fifth of the season against the run of play.
The goal seemed to spur on Milan and they then appeared the more likely winners.
Balotelli saw his thunderous free kick parried away by Morgan de Sanctis and the former Manchester City striker should have wrapped it up in injury time when through on goal but he dragged his shot wide.