diff --git a/src/actions/MatrixActionCreators.js b/src/actions/MatrixActionCreators.js
index dbfe910533..27fbb6dda5 100644
--- a/src/actions/MatrixActionCreators.js
+++ b/src/actions/MatrixActionCreators.js
@@ -66,6 +66,15 @@ function createRoomTagsAction(matrixClient, roomTagsEvent, room) {
     return { action: 'MatrixActions.Room.tags', room };
 }
 
+function createRoomTimelineAction(matrixClient, timelineEvent, room, toStartOfTimeline, removed, data) {
+    return {
+        action: 'MatrixActions.Room.timeline',
+        event: timelineEvent,
+        isLiveEvent: data.liveEvent,
+        room,
+    };
+}
+
 function createRoomMembershipAction(matrixClient, membershipEvent, member, oldMembership) {
     return { action: 'MatrixActions.RoomMember.membership', member };
 }
@@ -87,6 +96,7 @@ export default {
         this._addMatrixClientListener(matrixClient, 'sync', createSyncAction);
         this._addMatrixClientListener(matrixClient, 'accountData', createAccountDataAction);
         this._addMatrixClientListener(matrixClient, 'Room.tags', createRoomTagsAction);
+        this._addMatrixClientListener(matrixClient, 'Room.timeline', createRoomTimelineAction);
         this._addMatrixClientListener(matrixClient, 'RoomMember.membership', createRoomMembershipAction);
     },
 
diff --git a/src/components/views/rooms/RoomList.js b/src/components/views/rooms/RoomList.js
index 41a200420d..bab8054c60 100644
--- a/src/components/views/rooms/RoomList.js
+++ b/src/components/views/rooms/RoomList.js
@@ -76,7 +76,6 @@ module.exports = React.createClass({
 
         cli.on("Room", this.onRoom);
         cli.on("deleteRoom", this.onDeleteRoom);
-        cli.on("Room.timeline", this.onRoomTimeline);
         cli.on("Room.name", this.onRoomName);
         cli.on("Room.receipt", this.onRoomReceipt);
         cli.on("RoomState.events", this.onRoomStateEvents);
@@ -177,7 +176,6 @@ module.exports = React.createClass({
         if (MatrixClientPeg.get()) {
             MatrixClientPeg.get().removeListener("Room", this.onRoom);
             MatrixClientPeg.get().removeListener("deleteRoom", this.onDeleteRoom);
-            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
             MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
             MatrixClientPeg.get().removeListener("Room.receipt", this.onRoomReceipt);
             MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents);
@@ -236,13 +234,6 @@ module.exports = React.createClass({
         this._updateStickyHeaders(true, scrollToPosition);
     },
 
-    onRoomTimeline: function(ev, room, toStartOfTimeline, removed, data) {
-        if (toStartOfTimeline) return;
-        if (!room) return;
-        if (data.timeline.getTimelineSet() !== room.getUnfilteredTimelineSet()) return;
-        this._delayedRefreshRoomList();
-    },
-
     onRoomReceipt: function(receiptEvent, room) {
         // because if we read a notification, it will affect notification count
         // only bother updating if there's a receipt from us
diff --git a/src/stores/RoomListStore.js b/src/stores/RoomListStore.js
index fdd9ca6692..707a9da17e 100644
--- a/src/stores/RoomListStore.js
+++ b/src/stores/RoomListStore.js
@@ -23,6 +23,16 @@ import Unread from '../Unread';
  * the RoomList.
  */
 class RoomListStore extends Store {
+
+    static _listOrders = {
+        "m.favourite": "manual",
+        "im.vector.fake.invite": "recent",
+        "im.vector.fake.recent": "recent",
+        "im.vector.fake.direct": "recent",
+        "m.lowpriority": "recent",
+        "im.vector.fake.archived": "recent",
+    };
+
     constructor() {
         super(dis);
 
@@ -68,6 +78,14 @@ class RoomListStore extends Store {
                 this._generateRoomLists();
             }
             break;
+            case 'MatrixActions.Room.timeline': {
+                if (!this._state.ready ||
+                    !payload.isLiveEvent ||
+                    !this._eventTriggersRecentReorder(payload.event)
+                ) break;
+                this._generateRoomLists();
+            }
+            break;
             case 'MatrixActions.accountData': {
                 if (payload.event_type !== 'm.direct') break;
                 this._generateRoomLists();
@@ -159,18 +177,9 @@ class RoomListStore extends Store {
             }
         });
 
-        const listOrders = {
-            "m.favourite": "manual",
-            "im.vector.fake.invite": "recent",
-            "im.vector.fake.recent": "recent",
-            "im.vector.fake.direct": "recent",
-            "m.lowpriority": "recent",
-            "im.vector.fake.archived": "recent",
-        };
-
         Object.keys(lists).forEach((listKey) => {
             let comparator;
-            switch (listOrders[listKey]) {
+            switch (RoomListStore._listOrders[listKey]) {
                 case "recent":
                     comparator = this._recentsComparator;
                     break;
@@ -188,13 +197,17 @@ class RoomListStore extends Store {
         });
     }
 
+    _eventTriggersRecentReorder(ev) {
+        return ev.getTs() && (
+            Unread.eventTriggersUnreadCount(ev) ||
+            ev.getSender() === this._matrixClient.credentials.userId
+        );
+    }
+
     _tsOfNewestEvent(room) {
         for (let i = room.timeline.length - 1; i >= 0; --i) {
             const ev = room.timeline[i];
-            if (ev.getTs() &&
-                (Unread.eventTriggersUnreadCount(ev) ||
-                (ev.getSender() === this._matrixClient.credentials.userId))
-            ) {
+            if (this._eventTriggersRecentReorder(ev)) {
                 return ev.getTs();
             }
         }
@@ -210,6 +223,8 @@ class RoomListStore extends Store {
     }
 
     _recentsComparator(roomA, roomB) {
+        // XXX: We could use a cache here and update it when we see new
+        // events that trigger a reorder
         return this._tsOfNewestEvent(roomB) - this._tsOfNewestEvent(roomA);
     }