Milan are third in the standings on 26 points from 12 games, one point below second-placed Atalanta and six adrift of leaders Napoli, who both won their games this weekend and face each other in the next round.
Forward Rafael Leao should have put Milan ahead inside the opening 10 minutes when he received two great passes in or just outside the opponents' box, but missed the target badly on both occasions.
While Stefano Pioli's men dominated possession and looked to settle into the game as the half wore on, Torino took a surprise lead in the 35th minute through defender Koffi Djidji.
Aleksey Miranchuk doubled Torino's advantage two minutes later when goalkeeper Vanja Milinkovic-Savic sent a long ball up the field which landed just in front of Milan's area, and the midfielder fired a low shot inside the right post.
Defender Sergino Dest had a chance to score for Milan shortly after the break when he found space just outside Torino's box and struck powerfully, seeing the ball go just over the crossbar.
Milan hit back through midfielder Junior Messias who unleashed their first shot on target in the 67th minute, after an error by Milinkovic-Savic who left the goal uncovered and allowed the Brazilian to shoot into the empty net.
Milan lacked clear chances to draw level, allowing Torino to end their unbeaten run of 17 Serie A away matches, the longest across Europe's top five leagues.
"[This defeat leaves me with] disappointment, we could have done better," Pioli told a news conference.
"We knew it would be a dirty, difficult, physical [game]. But we should have moved better without the ball, we struggled to find solutions."
Milan, who need to avoid a defeat against RB Salzburg on Wednesday to progress to the Champions League knockout stage, host Spezia on Saturday.
Torino, who moved up to ninth on 17 points as they secured two successive league wins for the first time since January, travel to Bologna next Sunday.
Earlier on Sunday, fourth-placed Lazio suffered a surprise 3-1 home defeat by Salernitana after they went up through striker Mattia Zaccagni before halftime but conceded three goals in the second half.