为找到决战的理由,子玉派出使者宛春与晋国协商,提出了所谓的“休战”条件:晋国若允许曹、卫复国,楚军则撤离宋国。这实际上是子玉精心策划的一石三鸟之计,设想晋若同意休战条件,则曹、卫、宋三国将感激楚国;若晋不同意,则三国将会怨恨晋国。无论结果如何,晋国试图在中原争霸、号令诸侯的努力都将付诸东流。
先轸看穿了子玉的意图,巧妙设计反击,秘密与曹、卫两国达成协议,以断绝与楚国的关系为条件,答应恢复两国独立,同时扣押了楚国使者宛春,激怒子玉以求决战。曹、卫两国背叛楚国而投靠晋国,使者又被晋国扣押,子玉的傲慢与自负被彻底激起,倚仗楚、陈、蔡三国联军的强大兵力,趾高气昂地率军直逼陶丘,一心寻求与晋军决战的机会。
当年晋文公流亡楚国时,曾许诺楚成王,若晋楚两国在中原相遇交战,晋军将主动退避三舍以报答楚国的恩情。现今,晋楚两军果然狭路相逢,晋文公坚守信义,下令晋军从曹都陶丘后撤三舍,在城濮(今山东范县南)安营扎寨。齐、秦、宋等国军队随后也相继抵达城濮,与晋军会合。晋军退避三舍,表面看来是对楚成王的感恩回报,实则是为了避开楚军锋芒,诱敌深入,同时集结齐、秦等盟军,择机后发制人,一举击败楚军。
晋军主动撤退,楚军内部出现疑虑,有人主张暂停追击,保持观望态势。然而,独断专行的子玉认定晋军是胆怯退缩,视此为追击晋军、夺回曹、卫的最佳时机,遂率军急切追赶,直至城濮。
公元前632年四月,晋楚两军在城濮展开了一场大规模的战车对决。子玉将楚军分为中、左、右三军:楚军精锐作为中军,由子玉亲自指挥;陈、蔡军归属右军,由楚将子西统率;郑、许军归属左军,由子上统率。
晋军同样部署为三军:先轸担任元帅,统领中军;狐毛领军上军,郤溱、狐偃为副将;栾枝领军下军,胥臣为副将。
晋军通过对楚军实力的分析,发现楚中军实力最强,左右两翼相对较弱,且子玉过于自信,对晋军实际情况了解不足,因此决定针对楚军弱点,首先攻击其左右两翼,然后再集中力量冲击中军。
晋军统帅先轸下令,首先击破楚军较为薄弱的右翼,即陈、蔡两国军队。晋国下军副将胥臣领命应战,陈、蔡军队战马众多,攻势凌厉。胥臣机智地令麾下战马披上虎皮冲向敌阵,陈、蔡军队误以为真有猛虎袭来,恐慌之下纷纷溃散,楚军右翼瞬间崩溃。
子玉、子上见右军溃败,怒不可遏,对晋中军和上军发起猛烈进攻。晋军采取诱敌深入、分而歼之的战术应对楚左军的猛攻,晋上军佯装败退,主将狐毛特意将主、副将的两面大旗置于战车之上,然后缓缓撤退;晋下军主将栾枝为了进一步迷惑楚军,让战车拖曳树枝,在后方扬起滚滚尘埃。楚将子玉未能识破晋军计谋,误以为晋右翼确实败退,贸然命令楚左军追击,导致侧翼暴露。晋先轸、郤溱指挥中军从中截击,晋上军主将狐毛、副将狐偃也在此时率部回头夹击。楚左翼陷入重重包围,无路可退,迅速被晋军击溃。
子玉目睹左、右两军均遭败绩,大局已去,只好下令中军停止进攻,迅速撤离战场,从而使中军免遭覆灭。楚军战败后退守至连谷(今河南西华境内),子玉因战败遭受楚成王严厉指责,悲愤不已,最终自杀身亡。
城濮之战以晋军取得决定性胜利而落幕,楚国北上的步伐被有效遏制,被迫退回桐柏山、大别山以南地区,中原局势趋于稳定。战后,晋军进驻郑国衡雍,并在衡雍附近为周王修建行宫,向周王献上俘虏。周王亲自驾临践土慰劳晋军,并册封晋文公为“侯伯”。晋文公随即在践土召开会盟,邀请齐、鲁、宋、卫等七国国君参会,共订尊崇周王的盟约,晋国从此确立了在中原的霸主地位。
城濮之战是晋、楚两国争夺中原霸权的首次战略性决战。尽管在这场战争中,齐、秦两国仅给予晋国口头支持并未实际参战,楚军在兵力上占有优势,但晋军开创了灵活运用战略战术的先例,凭借智慧与谋略克敌制胜,并在战役指挥上采取了扬长避短、后发制人的正确方针,最终大败楚军,奠定了雄踞中原的基础。