Milan, enduring a nine-game winless streak against the Turin giants, are now just two points behind Juve.
A second-half screamer from Manuel Locatelli ended AC Milan's long wait for victory over Juventus in a contentious 1-0 San Siro win that saw an apparently valid Miralem Pjanic opener chalked off for the visitors.
Milan, enduring a nine-game winless streak against the Turin giants, are now just two points behind the reigning champions and league leaders.
In a San Siro spectacular that saw drama, controversy and a candidate for one of the Serie A goals of the season, Vincenzo Montella's men produced a battling performance to take their unbeaten run to six games.
Juventus, bidding for a record sixth consecutive scudetto, suffered only their second loss of the season and their second at the San Siro -- having lost 2-1 to Inter last month.
Juventus coach Massimiliano Allegri was given a hostile reception as the squad names were called out minutes before kick-off.
Although he was left grinning widest by the end of a dominant first-half that saw Milan's teenaged goalkeeper Gianluigi Donnarumma keep the hosts in the game, Allegri's last league visit to the San Siro this season was not positive.
Juventus were a class above early on, their compact, organised game producing chance after chance.
But Donnarumma showed why he should have no problem replacing Italy 'keeper Gianluigi Buffon in the near future.
As Milan lost their shape in defence, Dani Alves roamed the right flank to deliver for Alex Sandro, who was given to test a diving Donnarumma with a weak volley that went wide.
Donnarumma pulled off a brilliant save moments later when Alves rose to meet Pjanic's delivery to fire a header towards goal.
It took nearly 10 minutes for Milan to threaten, skipper Ignazio Abate's intercepting tackle on Pjanic sending Giacomo Bonaventura on a pacy run but the move broke down when Suso failed to reach Carlos Bacca's through ball.
But Juve were soon back in command, Paulo Dybala and Alves connecting for Sandro to test Donnarumma with a stooping header.
Gonzalo Higuain turned provider on 25 minutes, the striker setting up Sandro on the left but it was Dybala who raced in ahead of Higuain for the return, firing a low drive that Donnarumma collected down low.
Milan threatened briefly again, Paletta firing over for a corner that, after some ping pong in the box, saw Hernanes rush back to head clear.
Donnarumma was soon back in action, coming out smartly to collect Sami Khedira's cross with a spectacular mid-air dive as it edged towards Higuain.
Dybala was forced off on 33 minutes after pulling up with an apparent thigh injury to be replaced by Juan Cuadrado, the Colombian making his return to the fray four days after hitting the winner in a 1-0 Champions League win over Lyon.
Three minutes later, a low free kick from Pjanic ripped through bodies in the area to beat Donnarumma down low.
Milan's players appealed offside, and referee Nicola Rizzoli, after consultation with his fourth official, ruled in their favour. The decision came despite television replays suggesting the goal was valid.
A furious Juve resumed, however, in positive fashion after the restart, Higuain getting his right foot to Alves's cross to fire yards wide of Donnarumma's far post in the opening minutes.
Milan responded, M'Baye Niang firing a drive across goal that Ignazio Abate just could not reach, before plucking a goal from nowhere to send the vast majority of the 75,289 spectators into raptures.
Suso offloaded to an unmarked Locatelli who took a few steps before unleashing a right foot rocket that flew past Buffon to ping off the underside of the crossbar at his far corner.