Juve moved seven points clear at the summit with a 4-1 win over rival Torino earlier on Sunday (AEST) and Lazio was unable to close the gap by winning its game in hand.
Lazio had not lost in 16 home games since May 2019 but was two down at half-time, Ibrahimovic squeezing home a penalty after setting up Hakan Calhanoglu for the opener.
Ante Rebic added a third for Europe-chasing Milan in the second half as Lazio, without leading goalscorer Ciro Immobile, fell to just its second loss in 25 league matches.
Calhanoglu continued his good form since the restart by opening the scoring after 23 minutes, the midfielder's strike deflecting off Marco Parolo to help it over Thomas Strakosha.
Ibrahimovic had a goal ruled out for offside but did not have to wait long to score from the penalty spot after Alexis Saelemaekers's cross struck Stefan Radu's hand.
Strakosha got a hand to the spot-kick 11 minutes before the break but it squirmed under his body to leave Lazio, which recovered from a goal down to beat Fiorentina in midweek, with a big mountain to climb.
Manuel Lazzari thought that he had started a second-half comeback when he drilled home, only for the offside flag to deny him, and further misery followed when Rebic added a third goal.
The Croatia international took Giacomo Bonaventura's pass in his stride and swept past Strakosha for his ninth league goal of the season.
Milan should have added a fourth late on but Theo Hernandez missed a sitter, having earlier been denied by Strakosha after an impressive run.
Lazio's slim Scudetto hopes are surely all over as this loss leaves it seven points adrift of leader Juventus with eight games to go.
As for Milan, it now has 10 points from a possible 12 since the restart, the exception being a disappointing 2-2 draw with SPAL last time out, and is in sixth place.
Milan hosts league leader Juventus on Wednesday (AEST), the same day that Lazio, which will hope Stefano Pioli's men can do it a favour, travels to relegation-threatened Lecce.