diff --git a/chrome/browser/gtk/bookmark_editor_gtk.cc b/chrome/browser/gtk/bookmark_editor_gtk.cc
index 5aafc6c73609a2f6f1f46e0564502f71fc2d146f..f7cf7610cbedff42088e74fa834d25123cfa3fa7 100644
--- a/chrome/browser/gtk/bookmark_editor_gtk.cc
+++ b/chrome/browser/gtk/bookmark_editor_gtk.cc
@@ -7,6 +7,7 @@
 #include <gtk/gtk.h>
 
 #include "app/l10n_util.h"
+#include "app/menus/simple_menu_model.h"
 #include "base/basictypes.h"
 #include "base/logging.h"
 #include "base/string_util.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/gtk/bookmark_utils_gtk.h"
 #include "chrome/browser/gtk/gtk_theme_provider.h"
 #include "chrome/browser/gtk/gtk_util.h"
+#include "chrome/browser/gtk/menu_gtk.h"
 #include "chrome/browser/history/history.h"
 #include "chrome/browser/net/url_fixer_upper.h"
 #include "chrome/browser/profile.h"
@@ -37,6 +39,127 @@ static const int kTreeHeight = 150;
 
 }  // namespace
 
+class BookmarkEditorGtk::ContextMenuController
+    : public menus::SimpleMenuModel::Delegate {
+ public:
+  explicit ContextMenuController(BookmarkEditorGtk* editor)
+      : editor_(editor),
+        running_menu_for_root_(false) {
+    menu_model_.reset(new menus::SimpleMenuModel(this));
+    menu_model_->AddItemWithStringId(COMMAND_EDIT, IDS_EDIT);
+    menu_model_->AddItemWithStringId(
+        COMMAND_NEW_FOLDER,
+        IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM);
+    menu_.reset(new MenuGtk(NULL, menu_model_.get()));
+  }
+  virtual ~ContextMenuController() {}
+
+  void RunMenu() {
+    const BookmarkNode* selected_node = GetSelectedNode();
+    if (selected_node)
+      running_menu_for_root_ = selected_node->GetParent()->IsRoot();
+    menu_->PopupAsContext(gtk_get_current_event_time());
+  }
+
+  void Cancel() {
+    editor_ = NULL;
+    menu_->Cancel();
+  }
+
+ private:
+  enum ContextMenuCommand {
+    COMMAND_EDIT,
+    COMMAND_NEW_FOLDER
+  };
+
+  // Overridden from menus::SimpleMenuModel::Delegate:
+  virtual bool IsCommandIdEnabled(int command_id) const {
+    return !(command_id == COMMAND_EDIT && running_menu_for_root_) &&
+        (editor_ != NULL);
+  }
+
+  virtual bool IsCommandIdChecked(int command_id) const {
+    return false;
+  }
+
+  virtual bool GetAcceleratorForCommandId(int command_id,
+                                          menus::Accelerator* accelerator) {
+    return false;
+  }
+
+  virtual void ExecuteCommand(int command_id) {
+    if (!editor_)
+      return;
+
+    switch (command_id) {
+      case COMMAND_EDIT: {
+        GtkTreeIter iter;
+        if (!gtk_tree_selection_get_selected(editor_->tree_selection_,
+                                             NULL,
+                                             &iter)) {
+          return;
+        }
+
+        GtkTreePath* path = gtk_tree_model_get_path(
+            GTK_TREE_MODEL(editor_->tree_store_), &iter);
+        gtk_tree_view_expand_to_path(GTK_TREE_VIEW(editor_->tree_view_), path);
+
+        // Make the folder name editable.
+        gtk_tree_view_set_cursor(GTK_TREE_VIEW(editor_->tree_view_), path,
+            gtk_tree_view_get_column(GTK_TREE_VIEW(editor_->tree_view_), 0),
+            TRUE);
+
+        gtk_tree_path_free(path);
+        break;
+      }
+      case COMMAND_NEW_FOLDER:
+        editor_->NewFolder();
+        break;
+      default:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  int64 GetRowIdAt(GtkTreeModel* model, GtkTreeIter* iter) {
+    GValue value = { 0, };
+    gtk_tree_model_get_value(model, iter, bookmark_utils::ITEM_ID, &value);
+    int64 id = g_value_get_int64(&value);
+    g_value_unset(&value);
+    return id;
+  }
+
+  const BookmarkNode* GetNodeAt(GtkTreeModel* model, GtkTreeIter* iter) {
+    int64 id = GetRowIdAt(model, iter);
+    return (id > 0) ? editor_->bb_model_->GetNodeByID(id) : NULL;
+  }
+
+  const BookmarkNode* GetSelectedNode() {
+    GtkTreeModel* model;
+    GtkTreeIter iter;
+    if (!gtk_tree_selection_get_selected(editor_->tree_selection_,
+                                         &model,
+                                         &iter)) {
+      return NULL;
+    }
+
+    return GetNodeAt(model, &iter);
+  }
+
+  // The model and view for the right click context menu.
+  scoped_ptr<menus::SimpleMenuModel> menu_model_;
+  scoped_ptr<MenuGtk> menu_;
+
+  // The context menu was brought up for. Set to NULL when the menu is canceled.
+  BookmarkEditorGtk* editor_;
+
+  // If true, we're running the menu for the bookmark bar or other bookmarks
+  // nodes.
+  bool running_menu_for_root_;
+
+  DISALLOW_COPY_AND_ASSIGN(ContextMenuController);
+};
+
 // static
 void BookmarkEditor::Show(gfx::NativeWindow parent_hwnd,
                           Profile* profile,
@@ -181,6 +304,8 @@ void BookmarkEditorGtk::Init(GtkWindow* parent_window) {
     tree_view_ = bookmark_utils::MakeTreeViewForStore(tree_store_);
     gtk_widget_set_size_request(tree_view_, kTreeWidth, kTreeHeight);
     tree_selection_ = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_));
+    g_signal_connect(tree_view_, "button-press-event",
+                     G_CALLBACK(OnTreeViewButtonPressEventThunk), this);
 
     GtkTreePath* path = NULL;
     if (selected_id) {
@@ -396,6 +521,25 @@ void BookmarkEditorGtk::OnEntryChanged(GtkWidget* entry) {
 }
 
 void BookmarkEditorGtk::OnNewFolderClicked(GtkWidget* button) {
+  NewFolder();
+}
+
+gboolean BookmarkEditorGtk::OnTreeViewButtonPressEvent(GtkWidget* widget,
+                                                       GdkEventButton* event) {
+  if (event->button == 3)
+    ShowContextMenu();
+
+  return FALSE;
+}
+
+void BookmarkEditorGtk::ShowContextMenu() {
+  if (!menu_controller_.get())
+    menu_controller_.reset(new ContextMenuController(this));
+
+  menu_controller_->RunMenu();
+}
+
+void BookmarkEditorGtk::NewFolder() {
   GtkTreeIter iter;
   if (!gtk_tree_selection_get_selected(tree_selection_,
                                        NULL,
diff --git a/chrome/browser/gtk/bookmark_editor_gtk.h b/chrome/browser/gtk/bookmark_editor_gtk.h
index fda876910a31a31dcc632c6d247db27367547780..debec747b63fb3985c875e6a29274a541b87f987 100644
--- a/chrome/browser/gtk/bookmark_editor_gtk.h
+++ b/chrome/browser/gtk/bookmark_editor_gtk.h
@@ -9,6 +9,7 @@
 #include "app/gtk_integers.h"
 #include "app/gtk_signal.h"
 #include "base/gtest_prod_util.h"
+#include "base/scoped_ptr.h"
 #include "base/string16.h"
 #include "chrome/browser/bookmarks/bookmark_editor.h"
 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
@@ -16,6 +17,7 @@
 class GURL;
 
 typedef union  _GdkEvent GdkEvent;
+typedef struct _GdkEventButton GdkEventButton;
 typedef struct _GtkTreeIter GtkTreeIter;
 typedef struct _GtkTreeSelection GtkTreeSelection;
 typedef struct _GtkTreeStore GtkTreeStore;
@@ -47,6 +49,9 @@ class BookmarkEditorGtk : public BookmarkEditor,
   void Close();
 
  private:
+  class ContextMenuController;
+  friend class ContextMenuController;
+
   void Init(GtkWindow* parent_window);
 
   // BookmarkModel observer methods. Any structural change results in
@@ -104,6 +109,13 @@ class BookmarkEditorGtk : public BookmarkEditor,
 
   CHROMEGTK_CALLBACK_0(BookmarkEditorGtk, void, OnNewFolderClicked);
 
+  CHROMEGTK_CALLBACK_1(BookmarkEditorGtk, gboolean, OnTreeViewButtonPressEvent,
+                       GdkEventButton*);
+
+  void ShowContextMenu();
+
+  void NewFolder();
+
   // Profile the entry is from.
   Profile* profile_;
 
@@ -141,6 +153,9 @@ class BookmarkEditorGtk : public BookmarkEditor,
   // Is the tree shown?
   bool show_tree_;
 
+  // The context menu controller.
+  scoped_ptr<ContextMenuController> menu_controller_;
+
   DISALLOW_COPY_AND_ASSIGN(BookmarkEditorGtk);
 };