diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c
index 07bd357..372e90c 100644
--- a/libempathy-gtk/empathy-chat.c
+++ b/libempathy-gtk/empathy-chat.c
@@ -1795,6 +1795,8 @@ chat_members_changed_cb (EmpathyTpChat  *tp_chat,
 	const gchar *name = empathy_contact_get_name (contact);
 	gchar *str;
 
+	g_return_if_fail (TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED != reason);
+
 	if (priv->block_events_timeout_id != 0)
 		return;
 
@@ -1809,6 +1811,30 @@ chat_members_changed_cb (EmpathyTpChat  *tp_chat,
 	g_free (str);
 }
 
+static void
+chat_member_renamed_cb (EmpathyTpChat  *tp_chat,
+			 EmpathyContact *old_contact,
+			 EmpathyContact *new_contact,
+			 guint           reason,
+			 gchar          *message,
+			 EmpathyChat    *chat)
+{
+	EmpathyChatPriv *priv = GET_PRIV (chat);
+
+	g_return_if_fail (TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED == reason);
+
+	if (priv->block_events_timeout_id == 0) {
+		gchar *str;
+
+		str = g_strdup_printf (_("%s is now known as %s"),
+				       empathy_contact_get_name (old_contact),
+				       empathy_contact_get_name (new_contact));
+		empathy_chat_view_append_event (chat->view, str);
+		g_free (str);
+	}
+
+}
+
 static gboolean
 chat_reset_size_request (gpointer widget)
 {
@@ -2536,6 +2562,9 @@ empathy_chat_set_tp_chat (EmpathyChat   *chat,
 	g_signal_connect (tp_chat, "members-changed",
 			  G_CALLBACK (chat_members_changed_cb),
 			  chat);
+	g_signal_connect (tp_chat, "member-renamed",
+			  G_CALLBACK (chat_member_renamed_cb),
+			  chat);
 	g_signal_connect_swapped (tp_chat, "notify::remote-contact",
 				  G_CALLBACK (chat_remote_contact_changed_cb),
 				  chat);
diff --git a/libempathy-gtk/empathy-contact-list-store.c b/libempathy-gtk/empathy-contact-list-store.c
index 6572b4c..c516dbf 100644
--- a/libempathy-gtk/empathy-contact-list-store.c
+++ b/libempathy-gtk/empathy-contact-list-store.c
@@ -103,6 +103,12 @@ static void             contact_list_store_members_changed_cb        (EmpathyCon
 								      gchar                         *message,
 								      gboolean                       is_member,
 								      EmpathyContactListStore       *store);
+static void             contact_list_store_member_renamed_cb         (EmpathyContactList            *list_iface,
+								      EmpathyContact                *old_contact,
+								      EmpathyContact                *new_contact,
+								      guint                          reason,
+								      gchar                         *message,
+								      EmpathyContactListStore       *store);
 static void             contact_list_store_groups_changed_cb         (EmpathyContactList            *list_iface,
 								      EmpathyContact                *contact,
 								      gchar                         *group,
@@ -175,6 +181,10 @@ contact_list_store_iface_setup (gpointer user_data)
 
 	/* Signal connection. */
 	g_signal_connect (priv->list,
+			  "member-renamed",
+			  G_CALLBACK (contact_list_store_member_renamed_cb),
+			  store);
+	g_signal_connect (priv->list,
 			  "members-changed",
 			  G_CALLBACK (contact_list_store_members_changed_cb),
 			  store);
@@ -309,6 +319,9 @@ contact_list_store_dispose (GObject *object)
 	g_list_free (contacts);
 
 	g_signal_handlers_disconnect_by_func (priv->list,
+					      G_CALLBACK (contact_list_store_member_renamed_cb),
+					      object);
+	g_signal_handlers_disconnect_by_func (priv->list,
 					      G_CALLBACK (contact_list_store_members_changed_cb),
 					      object);
 	g_signal_handlers_disconnect_by_func (priv->list,
@@ -790,6 +803,38 @@ contact_list_store_inibit_active_cb (EmpathyContactListStore *store)
 }
 
 static void
+contact_list_store_add_contact_and_connect (EmpathyContactListStore *store, EmpathyContact *contact)
+{
+	g_signal_connect (contact, "notify::presence",
+			  G_CALLBACK (contact_list_store_contact_updated_cb),
+			  store);
+	g_signal_connect (contact, "notify::presence-message",
+			  G_CALLBACK (contact_list_store_contact_updated_cb),
+			  store);
+	g_signal_connect (contact, "notify::name",
+			  G_CALLBACK (contact_list_store_contact_updated_cb),
+			  store);
+	g_signal_connect (contact, "notify::avatar",
+			  G_CALLBACK (contact_list_store_contact_updated_cb),
+			  store);
+	g_signal_connect (contact, "notify::capabilities",
+			  G_CALLBACK (contact_list_store_contact_updated_cb),
+			  store);
+
+	contact_list_store_add_contact (store, contact);
+}
+
+static void
+contact_list_store_remove_contact_and_disconnect (EmpathyContactListStore *store, EmpathyContact *contact)
+{
+	g_signal_handlers_disconnect_by_func (contact,
+					      G_CALLBACK (contact_list_store_contact_updated_cb),
+					      store);
+
+	contact_list_store_remove_contact (store, contact);
+}
+
+static void
 contact_list_store_members_changed_cb (EmpathyContactList      *list_iface,
 				       EmpathyContact          *contact,
 				       EmpathyContact          *actor,
@@ -808,33 +853,38 @@ contact_list_store_members_changed_cb (EmpathyContactList      *list_iface,
 		is_member ? "added" : "removed");
 
 	if (is_member) {
-		g_signal_connect (contact, "notify::presence",
-				  G_CALLBACK (contact_list_store_contact_updated_cb),
-				  store);
-		g_signal_connect (contact, "notify::presence-message",
-				  G_CALLBACK (contact_list_store_contact_updated_cb),
-				  store);
-		g_signal_connect (contact, "notify::name",
-				  G_CALLBACK (contact_list_store_contact_updated_cb),
-				  store);
-		g_signal_connect (contact, "notify::avatar",
-				  G_CALLBACK (contact_list_store_contact_updated_cb),
-				  store);
-		g_signal_connect (contact, "notify::capabilities",
-				  G_CALLBACK (contact_list_store_contact_updated_cb),
-				  store);
-
-		contact_list_store_add_contact (store, contact);
+		contact_list_store_add_contact_and_connect (store, contact);
 	} else {
-		g_signal_handlers_disconnect_by_func (contact,
-						      G_CALLBACK (contact_list_store_contact_updated_cb),
-						      store);
-
-		contact_list_store_remove_contact (store, contact);
+		contact_list_store_remove_contact_and_disconnect (store, contact);
 	}
 }
 
 static void
+contact_list_store_member_renamed_cb (EmpathyContactList      *list_iface,
+				      EmpathyContact          *old_contact,
+				      EmpathyContact          *new_contact,
+				      guint                    reason,
+				      gchar                   *message,
+				      EmpathyContactListStore *store)
+{
+	EmpathyContactListStorePriv *priv;
+
+	priv = GET_PRIV (store);
+
+	DEBUG ("Contact %s (%d) renamed to %s (%d)",
+		empathy_contact_get_id (old_contact),
+		empathy_contact_get_handle (old_contact),
+		empathy_contact_get_id (new_contact),
+		empathy_contact_get_handle (new_contact));
+
+	/* add the new contact */
+	contact_list_store_add_contact_and_connect (store, new_contact);
+
+	/* remove old contact */
+	contact_list_store_remove_contact_and_disconnect (store, old_contact);
+}
+
+static void
 contact_list_store_groups_changed_cb (EmpathyContactList      *list_iface,
 				      EmpathyContact          *contact,
 				      gchar                   *group,
diff --git a/libempathy/empathy-contact-list.c b/libempathy/empathy-contact-list.c
index d9493af..d485921 100644
--- a/libempathy/empathy-contact-list.c
+++ b/libempathy/empathy-contact-list.c
@@ -54,6 +54,15 @@ contact_list_base_init (gpointer klass)
 	static gboolean initialized = FALSE;
 
 	if (!initialized) {
+		g_signal_new ("member-renamed",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST,
+			      0,
+			      NULL, NULL,
+			      _empathy_marshal_VOID__OBJECT_OBJECT_UINT_STRING,
+			      G_TYPE_NONE,
+			      4, EMPATHY_TYPE_CONTACT, EMPATHY_TYPE_CONTACT, G_TYPE_UINT, G_TYPE_STRING);
+
 		g_signal_new ("members-changed",
 			      G_TYPE_FROM_CLASS (klass),
 			      G_SIGNAL_RUN_LAST,
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 9285206..39c0f48 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -950,6 +950,83 @@ chat_lookup_contact (EmpathyTpChat *chat,
 	return NULL;
 }
 
+typedef struct
+{
+    TpHandle old_handle;
+    guint reason;
+    gchar *message;
+} ContactRenameData;
+
+static ContactRenameData *
+contact_rename_data_new (TpHandle handle,
+			 guint reason,
+			 const gchar* message)
+{
+	ContactRenameData *data = g_new (ContactRenameData, 1);
+	data->old_handle = handle;
+	data->reason = reason;
+	data->message = g_strdup (message);
+
+	return data;
+}
+
+static void
+contact_rename_data_free (ContactRenameData* data)
+{
+	g_free (data->message);
+	g_free (data);
+}
+
+static void
+tp_chat_got_renamed_contacts_cb (EmpathyTpContactFactory *factory,
+                                 guint                    n_contacts,
+                                 EmpathyContact * const * contacts,
+                                 guint                    n_failed,
+                                 const TpHandle          *failed,
+                                 const GError            *error,
+                                 gpointer                 user_data,
+                                 GObject                 *chat)
+{
+	EmpathyTpChatPriv *priv = GET_PRIV (chat);
+	const TpIntSet *members;
+	TpHandle handle;
+	EmpathyContact *old = NULL, *new = NULL;
+	ContactRenameData *rename_data = (ContactRenameData *) user_data;
+
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
+	/* renamed members can only be delivered one at a time */
+	g_warn_if_fail (n_contacts == 1);
+
+	new = contacts[0];
+
+	members = tp_channel_group_get_members (priv->channel);
+	handle = empathy_contact_get_handle (new);
+
+	old = chat_lookup_contact (EMPATHY_TP_CHAT (chat),
+				   rename_data->old_handle, TRUE);
+
+	/* Make sure the contact is still member */
+	if (tp_intset_is_member (members, handle)) {
+		priv->members = g_list_prepend (priv->members,
+			g_object_ref (new));
+
+		if (old != NULL) {
+			g_signal_emit_by_name (chat, "member-renamed",
+					       old, new, rename_data->reason,
+					       rename_data->message);
+			g_object_unref (old);
+		}
+	}
+
+	tp_chat_update_remote_contact (EMPATHY_TP_CHAT (chat));
+	tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
+}
+
+
 static void
 tp_chat_group_members_changed_cb (TpChannel     *self,
 				  gchar         *message,
@@ -965,6 +1042,25 @@ tp_chat_group_members_changed_cb (TpChannel     *self,
 	EmpathyContact *contact;
 	EmpathyContact *actor_contact = NULL;
 	guint i;
+	ContactRenameData *rename_data;
+	TpHandle old_handle;
+
+	/* Contact renamed */
+	if (reason == TP_CHANNEL_GROUP_CHANGE_REASON_RENAMED) {
+		/* there can only be a single 'added' and a single 'removed' handle */
+		g_warn_if_fail (removed->len == 1);
+		g_warn_if_fail (added->len == 1);
+
+		old_handle = g_array_index (removed, guint, 0);
+
+		rename_data = contact_rename_data_new (old_handle, reason, message);
+		empathy_tp_contact_factory_get_from_handles (priv->factory,
+			added->len, (TpHandle *) added->data,
+			tp_chat_got_renamed_contacts_cb,
+			rename_data, (GDestroyNotify) contact_rename_data_free,
+			G_OBJECT (chat));
+		return;
+	}
 
 	if (actor != 0) {
 		actor_contact = chat_lookup_contact (chat, actor, FALSE);
