窦建德率军经河南,攻克周桥、荥阳等地,水陆并进,很快就抵达成皋的东原,一直西向,以救洛阳。窦建德特地派使者到达唐军军营,给李世民送信,要求唐停止进攻洛阳,返回长安。面对来势汹汹的窦建德,李世民手下的将领陷入了争论。屈突通、封德彝、萧瑀等将领主张撤退,他们说:“王世充凭借坚固的洛阳城,我军连月攻打,都没有攻下,现在,窦建德又率数十万大军乘胜而来,兵锋正盛;我军疲惫不堪士气低落,如果腹背受敌,肯定会全军覆没,不如撤退保守新安等地避其锋芒,等时机再出来决战。”这个意见得到薛收、郭孝恪等人的强烈反对,他们认为:“王世充虽然凭借洛阳抵御我军,但是长期的攻打和围困,洛阳城破已经成了时间问题。而窦建德亲自统帅大军远道赴援,带的兵将都是精锐,刚打了胜仗,有骄兵的情绪。如果让王世充和窦建德合并一处,把河北的粮食和士兵给洛阳,那么如果开战,他们相互补充,里应外合,我军必败。现在我们应当留一部分士兵假装继续围困洛阳,如果王世充出兵,要尽量不和他交战。大王亲自率领骁勇精锐,磨快兵器,带着训练过的精锐,在半道先占据有利地形,等窦建德的到来,以逸待劳,一定能出其不意地将其打败。打败窦建德后,王世充自然也就会败亡,这正是一石二鸟的计策啊。”
听了将领们的争论,李世民说:“经过这么长时间的战争,王世充的将领已经损其大半,洛阳城中缺粮,上下离心,我们不用攻打,洛阳城指日可破。而窦建德刚刚打了一路的胜仗,将领骄傲,士卒疲惫,我们如果占据武牢,发动出其不意的进攻,必定能把他击败。如果不去攻打窦建德,窦建德一旦进入武牢,拿下周围的城池,和王世充合并,势力必然强大,我们怎么能将其打败呢?所以,郭孝恪等人说得有理,我决定出兵武牢关!”听到这个决定,屈突通等人又恳求李世民三思而行,李世民不答应。而是让屈突通等人辅助齐王李元吉围困洛阳,他自己率兵向东奔赴武牢。
武牢关也就是虎牢关,又称汜水关,因为避李渊的祖父李虎名号而被唐人称为武牢关。武牢关离洛阳城东只有一百多里,地势险要,一直是兵家必争之地。李世民抢先带领五百名精锐骁骑到武牢关,来对抗窦建德的数万兵马,其勇气和魄力可见一斑。等到窦建德的先行部队到达,李世民大喊“我乃秦王李世民!”窦建德的先行军大惊,被打了个猝不及防。窦建德得知消息,派出五千骑兵追杀过来,李世民假装逃走,把窦建德的五千骑兵引入埋伏,两边的程咬金、秦叔宝等人突然杀出,将窦建德的五千骑兵冲散,并杀死三百多人。窦建德受挫,不敢轻易进军,李世民又派大将王君廓率兵偷袭了窦建德的粮道,夺取了大批粮草,窦军的士气衰落下来。之后,唐军奉李世民的命令,故意在黄河北岸放马,引诱窦建德。窦建德率领大军从牛口出发,摆开二十多里的大军向武牢关扑来。李世民对将领说:“窦建德从山东起兵以来,没有遇到过强大的敌人,今天率领所有的士兵来攻武牢关,骄傲轻敌,我们只需坚守住关隘,等他们的勇气衰退、粮草不济的时候,再及时出兵,就能大破之!”
果然,战况的发展正如李世民的预料,扑赶上来的士兵,因为急行军,再加上天气炎热,都非常疲惫,开始松懈起来。甚至很多士兵纷纷找阴凉的地方歇脚,看见河流就抢着饮水,毫无纪律。李世民看见时机已到,就下令自己的人马全线出击。李世民的铁甲骑兵先渡过汜水,以逸待劳,勇猛地冲进窦建德的大军。窦建德正在营帐议事,忽然听到唐军杀到,急忙召集兵士迎战,可是在李世民的骑兵过后,大部队纷纷杀过来,四面杀入,窦建德的军队乱作一团,没有招架之力。窦建德见唐军来势汹汹,带领亲兵赶紧逃窜,退到武牢关,程咬金、秦叔宝等大将杀出,挡住了窦建德的退路,窦军看见唐军,丝毫没有了抵御的胆量,纷纷投降或者继续逃走。看到这个情景,唐军挥动大旗,大喊:“窦建德已经投降,其余投降者免死。”投降的人越来越多,窦建德率领残军继续抵抗,被唐军活捉。
武牢关消灭窦建德以后,秦王李世民押解着窦建德到洛阳城下,故意给王世充看。王世充看见窦建德被活捉,知道大势已去,非常恐惧,就召集诸将商议突围,准备南奔襄阳。王世充手下的将领不愿意突围,他们说:“我们本来指望夏王窦建德来支援,如今夏王已被俘,我们现在突围,根本无法成功,还不如投降。”迫于手下将领们的压力,王世充最终决定投降。投降这天,王世充身穿素衣,带领所谓的太子、大小官员及其他将领到唐军营门投降。这样,占据关东的王世充、窦建德势力被李世民艰难平定。武德四年七月,战功赫赫的秦王李世民凯旋。十月,唐高祖见到王世充,先是历数其罪行,然后下诏赦免王世充,贬他作为平民,将其和家眷安置到蜀中,并在闹市中将窦建德处斩。后王世充等人被仇家独孤修德等人杀死。