diff --git a/src/favorite-popup.ui b/src/favorite-popup.ui
new file mode 100644
index 0000000..1d67507
--- /dev/null
+++ b/src/favorite-popup.ui
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.10 -->
+  <object class="GtkStack" id="stack">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="transition-type">crossfade</property>
+    <child>
+      <object class="GtkScrolledWindow" id="scrolled-window">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="hscrollbar_policy">never</property>
+        <property name="shadow_type">in</property>
+        <child>
+          <object class="GtkTreeView" id="treeview">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="expand">True</property>
+            <property name="headers-visible">False</property>
+            <property name="hover-selection">True</property>
+            <child internal-child="selection">
+              <object class="GtkTreeSelection" id="treeview-selection"/>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkSpinner" id="spinner">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="width_request">16</property>
+        <property name="height_request">16</property>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/src/favoritePopup.js b/src/favoritePopup.js
new file mode 100644
index 0000000..fbcf17c
--- /dev/null
+++ b/src/favoritePopup.js
@@ -0,0 +1,143 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Author: Jonas Danielsson <jonas@threetimestwo.org>
+ */
+
+const Gtk = imports.gi.Gtk;
+
+const Lang = imports.lang;
+const Utils = imports.utils;
+
+const Columns = {
+    ICON: 0,
+    TEXT: 1
+};
+
+const FavoritePopup = new Lang.Class({
+    Name: 'FavoritePopup',
+    Extends: Gtk.Popover,
+
+    _init: function(relativeTo, numVisible) {
+        this._numVisible = numVisible;
+
+        let ui = Utils.getUIObject('favorite-popup', ['scrolled-window',
+                                                      'stack',
+                                                      'spinner',
+                                                      'treeview',]);
+
+        this._stack = ui.stack;
+        this._scrolledWindow = ui.scrolledWindow;
+        this._spinner = ui.spinner;
+        this._treeView = ui.treeview;
+
+        this._treeView.connect('button-press-event',
+                               this._onListButtonPress.bind(this));
+        this._initList();
+
+        this.height_request = this._cellHeight * this._numVisible;
+        this._scrolledWindow.set_min_content_height(this.height_request);
+
+        this.parent({ relative_to: relativeTo,
+                      width_request: 300,
+                      no_show_all: true,
+                      visible: true });
+
+        this.get_style_context().add_class('maps-popover');
+        this.add(this._stack);
+        this.hide();
+    },
+
+    _initList: function() {
+        let column = new Gtk.TreeViewColumn();
+
+        this._treeView.append_column(column);
+
+        let cell = new Gtk.CellRendererPixbuf({ xpad: 2 });
+        column.pack_start(cell, false);
+        column.add_attribute(cell, 'pixbuf', Columns.ICON);
+
+        cell = new Gtk.CellRendererText({ xpad: 8,
+                                          ypad: 8 });
+        column.pack_start(cell, true);
+        column.add_attribute(cell, 'markup', Columns.TEXT);
+
+        this._cellHeight = column.cell_get_size(null)[3];
+        this._cellHeight += cell.get_preferred_height(this._treeView)[0];
+    },
+
+    _onListButtonPress: function(widget, event) {
+        let path_valid, path;
+        let bool, coordX, coordY;
+
+        [bool, coordX, coordY] = event.get_coords();
+        [path_valid, path] = this._treeView.get_path_at_pos(coordX, coordY,
+                                                            null, null, null);
+        if (path_valid) {
+            let model = this.getModel();
+            let iter_valid, iter;
+
+            if (model === null)
+                return;
+
+            [iter_valid, iter] = model.get_iter(path);
+            if (!iter_valid)
+                return;
+
+            this.emit('selected', iter);
+        }
+    },
+
+    showSpinner: function() {
+        this._spinner.start();
+        this._stack.set_visible_child(this._spinner);
+
+        if (!this.get_visible())
+            this.show();
+    },
+
+    showResult: function() {
+        if (this._spinner.active)
+            this._spinner.stop();
+
+        this._stack.set_visible_child(this._scrolledWindow);
+
+        if (!this.get_visible())
+            this.show();
+    },
+
+    vfunc_show: function() {
+        this._treeView.columns_autosize();
+        this.parent();
+    },
+
+    vfunc_hide: function() {
+        if (this._spinner.active)
+            this._spinner.stop();
+
+        this.parent();
+    },
+
+    setModel: function(model) {
+        this._treeView.set_model(model);
+    },
+
+    getModel: function() {
+        return this._treeView.get_model();
+    },
+});
+Utils.addSignalMethods(FavoritePopup.prototype);
diff --git a/src/gnome-maps.data.gresource.xml b/src/gnome-maps.data.gresource.xml
index 6250d60..33ae8fc 100644
--- a/src/gnome-maps.data.gresource.xml
+++ b/src/gnome-maps.data.gresource.xml
@@ -5,6 +5,7 @@
     <file preprocess="xml-stripblanks">main-window.ui</file>
     <file preprocess="xml-stripblanks">zoom-control.ui</file>
     <file preprocess="xml-stripblanks">search-popup.ui</file>
+    <file preprocess="xml-stripblanks">favorite-popup.ui</file>
     <file preprocess="xml-stripblanks">context-menu.ui</file>
     <file alias="application.css">../data/gnome-maps.css</file>
     <file alias="zoom-in.png">../data/media/zoom-in.png</file>
diff --git a/src/gnome-maps.js.gresource.xml b/src/gnome-maps.js.gresource.xml
index cb9a57c..838e3ad 100644
--- a/src/gnome-maps.js.gresource.xml
+++ b/src/gnome-maps.js.gresource.xml
@@ -4,6 +4,7 @@
     <file>application.js</file>
     <file>config.js</file>
     <file>contextMenu.js</file>
+    <file>favoritePopup.js</file>
     <file>geoclue.js</file>
     <file>main.js</file>
     <file>mainWindow.js</file>
diff --git a/src/main-window.ui b/src/main-window.ui
index 5d6afc4..dd60c6b 100644
--- a/src/main-window.ui
+++ b/src/main-window.ui
@@ -77,6 +77,48 @@
           </packing>
         </child>
         <child>
+          <object class="GtkButton" id="mark-favorite-button">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="valign">center</property>
+            <property name="action-name">win.mark-favorite</property>
+            <style>
+              <class name="image-button"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="mark-favorite-button-image">
+                <property name="visible">True</property>
+                <property name="icon-size">1</property>
+                <property name="icon-name">emblem-favorite-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack-type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="list-favorite-button">
+            <property name="visible">True</property>
+            <property name="can-focus">True</property>
+            <property name="valign">center</property>
+            <property name="action-name">win.list-favorite</property>
+            <style>
+              <class name="image-button"/>
+            </style>
+            <child>
+              <object class="GtkImage" id="list-favorite-button-image">
+                <property name="visible">True</property>
+                <property name="icon-size">1</property>
+                <property name="icon-name">view-list-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack-type">end</property>
+          </packing>
+        </child>
+        <child>
           <object class="GtkMenuButton" id="layer-menu-button">
             <property name="visible">True</property>
             <property name="can-focus">True</property>
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 3f9fc96..bfcdc52 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -27,6 +27,7 @@ const GLib = imports.gi.GLib;
 const Gtk = imports.gi.Gtk;
 const GObject = imports.gi.GObject;
 const Champlain = imports.gi.Champlain;
+const Geocode = imports.gi.GeocodeGlib;
 
 const Lang = imports.lang;
 const Mainloop = imports.mainloop;
@@ -34,6 +35,7 @@ const Mainloop = imports.mainloop;
 const Application = imports.application;
 const MapView = imports.mapView;
 const SearchPopup = imports.searchPopup;
+const FavoritePopup = imports.favoritePopup;
 const ContextMenu = imports.contextMenu;
 const PlaceStore = imports.placeStore;
 const Utils = imports.utils;
@@ -47,6 +49,7 @@ const _WINDOW_MIN_WIDTH = 600;
 const _WINDOW_MIN_HEIGHT = 500;
 
 const _PLACE_ICON_SIZE = 20;
+const _NUM_FAVORITES = 10;
 
 const SearchResults = {
     COL_ICON:         0,
@@ -54,6 +57,12 @@ const SearchResults = {
     COL_PLACE:        2
 };
 
+const FavoriteList = {
+    COL_ICON:        0,
+    COL_DESCRIPTION: 1,
+    COL_PLACE:       2
+};
+
 const MainWindow = new Lang.Class({
     Name: 'MainWindow',
 
@@ -62,7 +71,10 @@ const MainWindow = new Lang.Class({
         let ui = Utils.getUIObject('main-window', [ 'app-window',
                                                     'window-content',
                                                     'search-entry',
-                                                    'search-completion']);
+                                                    'search-completion',
+                                                    'list-favorite-button']);
+
+        this._favoriteButton = ui.listFavoriteButton;
         this._searchEntry = ui.searchEntry;
         this._searchCompletion = ui.searchCompletion;
         this.window = ui.appWindow;
@@ -76,6 +88,7 @@ const MainWindow = new Lang.Class({
         this._contextMenu = new ContextMenu.ContextMenu(this.mapView);
 
         this._initPlaces();
+        this._initFavorites();
         this._initSearchWidgets();
         this._initActions();
         this._initSignals();
@@ -96,6 +109,97 @@ const MainWindow = new Lang.Class({
         }
     },
 
+    _initFavorites: function(){
+
+        Utils.initActions(this.window, [
+            {
+                properties: { name: 'mark-favorite' },
+                signalHandlers: { activate: this._onMarkFavoriteActivate }
+            }, {
+                properties: { name: 'list-favorite' },
+                signalHandlers: { activate: this._onListFavoriteActivate }
+            }
+        ], this);
+
+        this._favoritePopup = new FavoritePopup.FavoritePopup(this._favoriteButton, _NUM_FAVORITES);
+
+        let model = new Gtk.ListStore();
+        model.set_column_types([GdkPixbuf.Pixbuf,
+                                GObject.TYPE_STRING,
+                                GObject.TYPE_OBJECT]);
+
+        this._favoritePopup.setModel(model);
+
+        this._favoritePopup.connect('selected',
+                                  this._onListFavoriteSelected.bind(this));
+        this.mapView.view.connect('button-press-event',
+                                  this._favoritePopup.hide.bind(this._favoritePopup));
+
+    },
+
+    _onMarkFavoriteActivate: function(){
+        if (!this.mapView.geoclue.location)
+            return;
+
+        let place = Geocode.Place.new_with_location(this.mapView.geoclue.location.description,
+                                                    Geocode.PlaceType.UNKNOWN,
+                                                    this.mapView.geoclue.location);
+        this._placeStore.addFavorite(place);
+    },
+
+    _showFavoritesList: function(places) {
+        let model = this._favoritePopup.getModel();
+
+        if (places === null) {
+            this._favoritePopup.hide();
+            return;
+        }
+
+        places.forEach((function(place) {
+            let iter = model.append();
+            let location = place.get_location();
+            let icon = place.icon;
+
+            if (location == null)
+                return;
+
+            let description = GLib.markup_escape_text(location.description, -1);
+
+            model.set(iter,
+                      [FavoriteList.COL_DESCRIPTION,
+                       FavoriteList.COL_PLACE],
+                      [description,
+                       place]);
+
+            if (icon !== null) {
+                Utils.load_icon(icon, _PLACE_ICON_SIZE, function(pixbuf) {
+                    model.set(iter, [FavoriteList.COL_ICON], [pixbuf]);
+                });
+            }
+        }).bind(this));
+        this._favoritePopup.showResult();
+    },
+
+    _onListFavoriteActivate: function(){
+        let model = this._favoritePopup.getModel();
+
+        model.clear();
+        this._favoritePopup.showSpinner();
+
+        this._showFavoritesList(this._placeStore.getFavorites());
+
+    },
+
+    _onListFavoriteSelected: function(widget, iter) {
+        let model = this._favoritePopup.getModel();
+        let place = model.get_value(iter, FavoriteList.COL_PLACE);
+
+        this.mapView.showNGotoLocation(place);
+
+        this._placeStore.addRecent(place);
+        this._favoritePopup.hide();
+    },
+
     _initSearchWidgets: function() {
         this._searchPopup = new SearchPopup.SearchPopup(this._searchEntry, 10);
 
@@ -387,4 +491,5 @@ const MainWindow = new Lang.Class({
         aboutDialog.connect('response',
                             aboutDialog.destroy.bind(aboutDialog));
     }
+
 });
diff --git a/src/placeStore.js b/src/placeStore.js
index cb0a98f..42a7ba2 100644
--- a/src/placeStore.js
+++ b/src/placeStore.js
@@ -82,6 +82,19 @@ const PlaceStore = new Lang.Class({
         this._addPlace(place, PlaceType.FAVORITE, new Date().getTime());
     },
 
+    getFavorites: function(){
+    	let places = [];
+    	this.foreach(function(model, path, iter) {
+            let place    = model.get_value(iter, Columns.PLACE),
+                type     = model.get_value(iter, Columns.TYPE);
+
+            if(type == PlaceType.FAVORITE)
+            	places.push(place);
+        });
+
+        return places;
+    },
+
     addRecent: function(place) {
         if (this._exists(place, PlaceType.RECENT)) {
             this._updateAddTime(place);
