The hosts held the lead in a tense clash in Naples for the majority of the contest after captain Lorenzo Insigne broke the deadlock with a well-taken penalty after 11 minutes.
- Don't have ESPN? Get instant access
Chasing a first Scudetto since 1990, Napoli looked nervy as they went in search of three points that would have closed the gap on leaders AC Milan, with Roma having several chances to level in the second half.
The home side looked like they had done enough to hold on as the clock passed 90 minutes, before substitute El Shaarawy broke Napoli hearts in stoppage time, firing a leveller that in-form Roma deserved.
The draw left Napoli third in the standings on 67 points from 33 matches, four points behind leaders AC Milan. Roma stayed fifth on 58 points having stretched their unbeaten run in Serie A to 12 matches.
"There is a bit of disappointment, as for long stretches we controlled the game," Napoli coach Luciano Spalletti said. "We then faced a strong team that created problems.
"We are sorry for the final result, we had fresh players at the end but we were unable to manage the ball and the goal conceded was highly avoidable."
Insigne's cool finish ensured Napoli are the team with the most penalties scored in the big-five European leagues (nine).
Roma had one more gilt-edged chance and El Shaarawy arrowed the ball into the bottom corner. The Italian has scored all of his Serie A goals this campaign from the 90th minute onwards.
Roma coach Jose Mourinho was typically still not happy after the match, with the referee the target of his ire for not awarding his side a late penalty and giving a red card to unused away substitute Daniel Fuzato for his protests.
"Today it seemed impossible for us to win," he told DAZN. "[Referee Marco] Di Bello in some moments made me ashamed of being there.
"There was a red for [Alessandro] Zanoli, he didn't call a penalty against [Nicolo] Zaniolo and then much more. I have had enough, we want a little respect."