A stoppage-time equaliser for Zenit in an entertaining game denied Chelsea top spot in the group and they now qualify as runners-up, behind Juventus.
The Blues knew, going into the final round of games, that they had to at least match Juventus' result to secure top spot and the easier - in theory - last 16 draw that goes with that.
As it turned out, Thomas Tuchel's side may have to do things the hard way after drawing 3-3 in St. Petersburg, while Juventus edged out Malmo 1-0 in Turin.
Chelsea took the lead early on thanks to Timo Werner and looked reasonably comfortable until Zenit stunned them with a two-minute double salvo before the break.
First, Claudinho found space in the box to head home an excellent Douglas Santos cross. Then, Malcom played a defence splitting pass which sent Sardar Azmoun one-on-one with Kepa, who he duly rounded before finishing.
In the second half it was Chelsea's turn to stage a comeback with Romelu Lukaku applying a simple finish to a well-worked move just after the hour mark before Werner showed great feet in the box to put Chelsea ahead with five minutes to go.
Chelsea looked to be heading for top spot and a seeded last 16 draw, until deep in stoppage time when the ball fell to Aleksandr Erokhin on the edge of the box and his stunning half-volley earned Zenit a deserved point.
Juventus had taken care of their business, so they finish first, Chelsea second, Zenit third and Malmo bottom. The Russian side will, therefore, drop into the Europa League, a fate they had already guaranteed before tonight, but where they will prove a formidable opponent for most sides, as Chelsea will testify to.