Theo Hernandez put the visitors in front in the first half, but strikes from Giovanni Di Lorenzo and Dries Mertens either side of half-time turned the game on its head.
Kessie’s 73rd-minute spot kick levelled the scores to rescue a point for the Rossoneri, but they were reduced to 10 men for the final few minutes when substitute Alexis Saelemaekers earned two bookings in the space of three minutes.
The result leaves Napoli in sixth, two points behind Roma and two ahead of seventh-placed Milan.
Napoli started brightly as Mertens and Jose Callejon were denied from close range by Gianluigi Donnarumma and Lorenzo Insigne had a shot deflected onto the foot of the post, albeit by a teammate in an offside position.
But Milan opened the scoring against the run of play after 20 minutes with a fine team move. Ismael Bennacer’s through ball found Ante Rebic inside the area, and the Croatian pivoted and sent a cross into the path of Hernandez to hammer home a volley at the back post.
Napoli didn’t have to wait long to find the equaliser, as a deep free-kick evaded everyone and was weakly pushed out by the blind-sighted Donnarumma into the path of Di Lorenzo for a tap-in.
The home side completed the turnaround with an hour on the clock, when Callejon got to the byline and pulled a pass back to Mertens, whose first-time finish took a deflection before squeezing under Donnarumma.
But the visitors mustered a response when substitute Giacomo Bonaventura was tripped by Nikola Maksimovic to earn his side a penalty, which Kessie coolly converted.
Stefano Pioli’s side played out the final few minutes with 10 men after Saelemaekers went through the back of Eljif Elmas to earn a second yellow card just minutes after picking up his first.