The city rivals came into Thursday's fixtures each in with a chance of securing the crown - while Zenit travelled to Kuban Krasnodar also hoping to win the league.
CSKA entered the round top of the league on 61 points, with Zenit on 60 in second and third-placed Lokomotiv a further point back.
Zenit were comfortable 4-1 winners, but Zoran Tosic grabbed CSKA's crucial goal as they secured their 12th national title.
Andre-Villas Boas' side came into the game under a cloud after Sunday's encounter with Dinamo Moscow had to be abandoned due to a violent pitch invasion.
But they seized the advantage at Kuban Stadium and were temporarily top when Danny slipped Axel Witsel clear on goal for a 15th-minute opener.
Goalkeeper Vyacheslav Malafeev was forced off with injury soon after and replaced by Yuri Lodygin to keep Zenit nerves jangling.
Meanwhile in Moscow, CSKA defender Vasili Berezutski headed wide from a free-kick as the hosts at Arena Khimki went in search of a precious goal.
Zenit were two up at the break and cruising, Salomon Rondon heading home to double the advantage from Domenico Criscito's cross and a nervy CSKA display saw them go in at half-time goalless - leaving the St Petersburg club 45 minutes away from glory.
However, Leonid Slutsky's team talk revived his side and they finally went ahead in the first minute of the second period.
Tosic pounced on a loose pass in the Lokomotiv midfield before surging forward and drilling a low effort in from 20 yards.
News eventually reached Kuban as Zenit fans watched on deflated, but Oleg Shatov's volley to make it 3-1 cheered them somewhat.
Lorenzo Melgarejo grabbed a consolation for Kuban while, almost exactly at the same time in Moscow, Alan Dzagoev went agonisingly close to sealing CSKA's triumph.
It almost proved costly as Lokomotiv substitute Dame N'Doye hit the post but Slutsky's men held on - Hulk's fourth for Zenit coming after the final whistle in Moscow had blown and counting for nothing.
Elsewhere on the final day, Krasnodar secured UEFA Europa League football for the first time thanks to a 2-2 draw at Amkar Perm.
They will be joined by Lokomotiv and Dinamo Moscow, who lost 3-2 to city rivals Spartak - denied their own top-five spot due to an inferior head-to-head record with Krasnodar.
Matters at the bottom of the table had been decided ahead of the final day. Relegated pair Volga and Anzhi ended their miserable campaigns with home defeats to Ural and Krylya Sovetov respectively.
Krylya's win will boost their confidence heading into the relegation play-offs, and Tom Tomsk also grabbed a win ahead of their own participation - beating Rostov 3-2.
Elsewhere, Rubin Kazan and Terek Grozny rounded off their campaigns with a 1-1 draw.
Get the best features, fun and footballing frolics straight to your inbox every week.