diff --git a/configure.ac b/configure.ac
index 91bd284..d212154 100644
--- a/configure.ac
+++ b/configure.ac
@@ -464,6 +464,25 @@ AM_CONDITIONAL(HAVE_CONTROL_CENTER_EMBEDDING, test "x$have_control_center_embedd
 AC_SUBST(CONTROL_CENTER_EMBEDDING_CFLAGS)
 AC_SUBST(CONTROL_CENTER_EMBEDDING_LIBS)
 
+# Optional dependency for avatar selection
+AC_ARG_WITH([cheese],
+            AS_HELP_STRING([--with-cheese], [enable cheese webcam support]),,
+            with_cheese=auto)
+
+if test x"$with_cheese" != x"no" ; then
+   PKG_CHECK_MODULES(CHEESE, gstreamer-0.10 cheese-gtk >= 2.91.91.1, [have_cheese=yes], [have_cheese=no])
+   if test x${have_cheese} = xyes; then
+     AC_DEFINE(HAVE_CHEESE, 1, [Define to 1 to enable cheese webcam support])
+   fi
+   if test x${with_cheese} = xyes && test x${have_cheese} = xno; then
+     AC_MSG_ERROR([Cheese configured but not found])
+   fi
+else
+   have_cheese=no
+fi
+AM_CONDITIONAL(BUILD_CHEESE, test x${have_cheese} = xyes)
+
+
 # -----------------------------------------------------------
 # Coding style checks
 # -----------------------------------------------------------
@@ -509,6 +528,7 @@ Configure summary:
 	Adium themes (Webkit).......:  ${have_webkit}
 	Meego widgets ..............:  ${have_meego}
 	Control center embedding....:  ${have_control_center_embedding}
+	Cheese webcam support ......:  ${have_cheese}
 
     Connectivity:
 	NetworkManager integration..:  ${have_nm}
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am
index 18f9a1c..42e8801 100644
--- a/libempathy-gtk/Makefile.am
+++ b/libempathy-gtk/Makefile.am
@@ -16,6 +16,10 @@ AM_CPPFLAGS =                                           \
 	$(WARN_CFLAGS)					\
 	$(DISABLE_DEPRECATED)
 
+if BUILD_CHEESE
+AM_CPPFLAGS += $(CHEESE_CFLAGS)
+endif
+
 BUILT_SOURCES = 					\
 	empathy-gtk-marshal.h				\
 	empathy-gtk-marshal.c				\
@@ -169,6 +173,11 @@ libempathy_gtk_la_LIBADD =			\
 	$(WEBKIT_LIBS)				\
 	$(top_builddir)/libempathy/libempathy.la
 
+if BUILD_CHEESE
+libempathy_gtk_la_LIBADD += $(CHEESE_LIBS)
+endif
+
+
 check_c_sources = \
     $(libempathy_gtk_handwritten_source) \
     $(libempathy_gtk_headers)
diff --git a/libempathy-gtk/empathy-avatar-chooser.c b/libempathy-gtk/empathy-avatar-chooser.c
index 562961a..0ff7b4a 100644
--- a/libempathy-gtk/empathy-avatar-chooser.c
+++ b/libempathy-gtk/empathy-avatar-chooser.c
@@ -36,6 +36,11 @@
 #include "empathy-images.h"
 #include "empathy-ui-utils.h"
 
+#ifdef HAVE_CHEESE
+#include <cheese-avatar-chooser.h>
+#endif /* HAVE_CHEESE */
+
+
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
 
@@ -60,6 +65,14 @@
 #define AVATAR_SIZE_VIEW 64
 #define DEFAULT_DIR DATADIR"/pixmaps/faces"
 
+#ifdef HAVE_CHEESE
+/*
+ * A custom GtkResponseType used when the user presses the
+ * "Camera Picture" button. Any positive value would be sufficient.
+ */
+#define EMPATHY_FILE_CHOOSER_CAMERA_PICTURE 10
+#endif
+
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAvatarChooser)
 typedef struct {
 	TpConnection            *connection;
@@ -875,6 +888,52 @@ avatar_chooser_update_preview_cb (GtkFileChooser       *file_chooser,
 	gtk_file_chooser_set_preview_widget_active (file_chooser, TRUE);
 }
 
+#ifdef HAVE_CHEESE
+static gboolean
+destroy_chooser (GtkWidget *chooser)
+{
+	gtk_widget_destroy (chooser);
+	return FALSE;
+}
+
+static void
+webcam_response_cb (GtkDialog            *dialog,
+		    int                  response,
+		    EmpathyAvatarChooser *chooser)
+{
+	if (response == GTK_RESPONSE_ACCEPT) {
+		GdkPixbuf *pb;
+		/* TODO: decide on a propper place to this image */
+		const char *filename = "/tmp/empathy-avatar.jpg";
+
+		g_object_get (G_OBJECT (dialog), "pixbuf", &pb, NULL);
+
+
+		gdk_pixbuf_save (pb, filename, "jpeg", NULL, NULL);
+		avatar_chooser_set_image_from_file (chooser, filename);
+		g_object_unref (pb);
+	}
+	if (response != GTK_RESPONSE_DELETE_EVENT &&
+	    response != GTK_RESPONSE_NONE)
+		g_idle_add ((GSourceFunc) destroy_chooser, dialog);
+}
+
+static void
+choose_avatar_from_webcam (GtkWidget            *widget,
+			   EmpathyAvatarChooser *chooser)
+{
+	GtkWidget *window;
+
+	window = cheese_avatar_chooser_new ();
+	gtk_window_set_transient_for (GTK_WINDOW (window),
+				      GTK_WINDOW (gtk_widget_get_toplevel (widget)));
+	gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+	g_signal_connect (G_OBJECT (window), "response",
+			  G_CALLBACK (webcam_response_cb), chooser);
+	gtk_widget_show (window);
+}
+#endif /* HAVE_CHEESE */
+
 static void
 avatar_chooser_response_cb (GtkWidget            *widget,
 			    gint                  response,
@@ -905,7 +964,12 @@ avatar_chooser_response_cb (GtkWidget            *widget,
 		/* This corresponds to "No Image", not to "Cancel" */
 		avatar_chooser_clear_image (chooser);
 	}
-
+	#ifdef HAVE_CHEESE
+	else if (response == EMPATHY_FILE_CHOOSER_CAMERA_PICTURE) {
+		/* This corresponds to "Camera Picture" */
+		choose_avatar_from_webcam(widget, chooser);
+	}
+	#endif
 	gtk_widget_destroy (widget);
 }
 
@@ -930,6 +994,10 @@ avatar_chooser_clicked_cb (GtkWidget            *button,
 		gtk_file_chooser_dialog_new (_("Select Your Avatar Image"),
 					     empathy_get_toplevel_window (GTK_WIDGET (chooser)),
 					     GTK_FILE_CHOOSER_ACTION_OPEN,
+					     #ifdef HAVE_CHEESE
+					     _("Camera Picture"),
+					     EMPATHY_FILE_CHOOSER_CAMERA_PICTURE,
+					     #endif
 					     _("No Image"),
 					     GTK_RESPONSE_NO,
 					     GTK_STOCK_CANCEL,
