diff --git a/modules/geolocation_mapbox/geolocation_mapbox.css b/modules/geolocation_mapbox/geolocation_mapbox.css
new file mode 100644
index 0000000..cae284b
--- /dev/null
+++ b/modules/geolocation_mapbox/geolocation_mapbox.css
@@ -0,0 +1,71 @@
+
+/**
+ * @file
+ * CSS for Mapbox widget of Geolocation field.
+ */
+
+.geolocation-address-geocode,
+.geolocation-client-location {
+  background-color:#96BC44;
+  color:#FFF;
+  padding:2px 10px 3px 10px;
+  cursor:pointer;
+  margin:2px 0 0 4px;
+}
+
+.field-widget-geolocation-mapbox {
+  /* Clear floated elements */
+  overflow: auto;
+}
+
+.geolocation-address-geocode:hover,
+.geolocation-client-location:hover {
+  background-color:#999;
+}
+
+.geolocation-help,
+.geolocation-map {
+  margin: 1em 0;
+}
+
+.geolocation-lat-item,
+.geolocation-lng-item {
+  float: left;
+  margin-right: 1em;
+}
+.geolocation-lat,
+.geolocation-lng {
+  display: none;
+}
+
+.geolocation-lng-item label,
+.geolocation-lat-item label {
+  display: inline;
+}
+
+.geolocation-lng .form-disabled input.form-text,
+.geolocation-lat .form-disabled input.form-text {
+  background: transparent;
+  border: 0;
+  outline: 0;
+}
+
+.geolocation-address .form-type-textfield {
+  float: left;
+}
+
+.geolocation-remove {
+  float: right;
+}
+
+.geolocation-remove span {
+  background-color: #CC0000;
+  color: #FFF;
+  padding: 2px 10px 3px 10px;
+  cursor: pointer;
+  margin: 2px 0 0 4px;
+}
+
+.geolocation-remove span:hover {
+  background-color: #999;
+}
\ No newline at end of file
diff --git a/modules/geolocation_mapbox/geolocation_mapbox.info b/modules/geolocation_mapbox/geolocation_mapbox.info
new file mode 100644
index 0000000..00352dc
--- /dev/null
+++ b/modules/geolocation_mapbox/geolocation_mapbox.info
@@ -0,0 +1,4 @@
+name = Geolocation Mapbox
+description = Provides Mapbox widgets and formaters for geolocation field.
+package = Geolocation
+core = 7.x
diff --git a/modules/geolocation_mapbox/geolocation_mapbox.module b/modules/geolocation_mapbox/geolocation_mapbox.module
new file mode 100644
index 0000000..58e35bd
--- /dev/null
+++ b/modules/geolocation_mapbox/geolocation_mapbox.module
@@ -0,0 +1,281 @@
+<?php
+/**
+ * @file
+ * Mapbox widget and formaters for Geolocation.
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function geolocation_mapbox_menu() {
+  $items['admin/config/services/mapbox'] = array(
+    'title' => 'Geolocation Mapbox',
+    'description' => 'Configure Geolocation Mapbox settings',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('geolocation_mapbox_admin_settings'),
+    'access arguments' => array('administer site configuration'),
+    'type' => MENU_NORMAL_ITEM,
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function geolocation_mapbox_field_widget_info() {
+  return array(
+    'geolocation_mapbox' => array(
+      'label' => t('MapBox'),
+      'field types' => array('geolocation_latlng', 'geofield'),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_settings_form().
+ */
+function geolocation_mapbox_field_widget_settings_form($field, $instance) {
+  $widget = $instance['widget'];
+  $settings = $widget['settings'];
+
+  $form['scrollwheel'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Scroll Zoom'),
+    '#description' => t('By default zooming is done with double click and/or using the map controls to avoid interrupting the normal window scroll. It can optionally be enabled here.'),
+    '#default_value' => isset($settings['scrollwheel']) ? $settings['scrollwheel'] : FALSE,
+  );
+  $form['marker_draggable'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Draggable Marker'),
+    '#description' => t('Enabling this will allow the user to drag/drop the marker to select a location.'),
+    '#default_value' => isset($settings['marker_draggable']) ? $settings['marker_draggable'] : FALSE,
+  );
+
+  return $form;
+}
+
+/**
+ * Implements hook_field_widget_form().
+ */
+function geolocation_mapbox_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
+  if ($instance['widget']['type'] != 'geolocation_mapbox') {
+    return;
+  }
+
+  // In order to make Geolocation field work with the popular Field collection module
+  // we check if our map widget is part of a Field collection and add the
+  // #field_parents delta.
+  if ($instance['entity_type'] == 'field_collection_item') {
+    $depth = count($element['#field_parents']) - 1;
+    $parent_delta = $element['#field_parents'][$depth];
+    $id = $instance['id'] . '-' . $parent_delta . '-' . $delta;
+  }
+  else {
+    $id = $instance['id'] . '-' . $delta;
+  }
+
+  $lat_value = isset($items[$delta]['lat']) ? $items[$delta]['lat'] : NULL;
+  // To make this widget compatible with geofiled we need to rename the keys for
+  // longitude. Geofield uses "lon" while Geolocation Field uses "lng".
+  if ($field['type'] == 'geofield') {
+    $lng_value = isset($items[$delta]['lon']) ? $items[$delta]['lon'] : NULL;
+  }
+  else {
+    $lng_value = isset($items[$delta]['lng']) ? $items[$delta]['lng'] : NULL;
+  }
+  $element += array(
+    '#delta' => $delta,
+  );
+
+  $element['address'] = array(
+    '#type' => 'item',
+    '#title' => $element['#title'],
+    '#prefix' => '<div id="geolocation-address-' . $id . '" class="geolocation-address">',
+    '#suffix' => '</div>',
+    '#required' => $instance['required'],
+  );
+  $element['address']['field'] = array(
+    '#type' => 'textfield',
+    '#maxlength' => 120,
+  );
+  $element['address']['geocode'] = array(
+    '#prefix' => '<span id="geolocation-address-geocode-' . $id . '" class="geolocation-address-geocode">',
+    '#suffix' => '</span>',
+    '#markup' => t('Get location'),
+  );
+  $element['help'] = array(
+    '#prefix' => '<div id="geolocation-help-' . $id . '" class="geolocation-help">',
+    '#suffix' => '</div>',
+    '#markup' => t('Enter an address / location in the textfield or you can also click on the map to set a marker'),
+  );
+  $element['mapbox'] = array(
+    '#prefix' => '<div id="geolocation-map-' . $id . '" class="geolocation-map" style="width:100%;height:400px;">',
+    '#suffix' => '</div>',
+  );
+  // Presentational item.
+  $element['latitem'] = array(
+    '#type' => 'item',
+    '#title' => t('Latitude:'),
+    '#prefix' => '<div id="geolocation-lat-item-' . $id . '" class="geolocation-lat-item">',
+    '#suffix' => '</div>',
+    '#markup' => '<span class="geolocation-lat-item-value">' . $lat_value . '</span>',
+    '#required' => $instance['required'],
+  );
+  $element['lat'] = array(
+    '#type' => 'hidden',
+    '#prefix' => '<div id="geolocation-lat-' . $id . '" class="geolocation-lat">',
+    '#suffix' => '</div>',
+    '#default_value' => $lat_value,
+  );
+  // Presentational item.
+  $element['lngitem'] = array(
+    '#type' => 'item',
+    '#title' => t('Longitude:'),
+    '#prefix' => '<div id="geolocation-lng-item-' . $id . '" class="geolocation-lng-item">',
+    '#suffix' => '</div>',
+    '#markup' => '<span class="geolocation-lat-item-value">' . $lat_value . '</span>',
+    '#required' => $instance['required'],
+  );
+  $element['lng'] = array(
+    '#type' => 'hidden',
+    '#prefix' => '<div id="geolocation-lng-' . $id . '" class="geolocation-lng">',
+    '#suffix' => '</div>',
+    '#default_value' => $lng_value,
+  );
+  $element['remove'] = array(
+    '#prefix' => '<div id="geolocation-remove-' . $id . '" class="geolocation-remove"><span>',
+    '#suffix' => '</span></div>',
+    '#markup' => t('Remove'),
+  );
+
+  // Attach CSS and JS files via FAPI '#attached'.
+  $element['mapbox']['#attached']['css'][] = drupal_get_path('module', 'geolocation_mapbox') . '/geolocation_mapbox.css';
+  $element['mapbox']['#attached']['js'][] = array(
+    'data' => drupal_get_path('module', 'geolocation_mapbox') . '/geolocation_mapbox_widget.js',
+    'type' => 'file',
+    'scope' => 'footer',
+  );
+  geolocation_mapbox_attach_mapbox_assets($element);
+
+  // Make defaults available as javascript settings. In JS files use:
+  // Drupal.settings.mapDefaults.lat
+  $map_defaults_lat = ($lat_value) ? $lat_value : '';
+  $map_defaults_lng = ($lng_value) ? $lng_value : '';
+  $map_defaults = array(
+    $id => array(
+      'lat' => $map_defaults_lat,
+      'lng' => $map_defaults_lng,
+    ),
+  );
+  $mapbox_access_token = array(
+    'accessToken' => variable_get('geolocation_mapbox_access_token', ''),
+  );
+  $settings = array_merge($instance['widget']['settings'], $mapbox_access_token);
+  $data = array(
+    'defaults' => $map_defaults,
+    'settings' => $settings,
+  );
+  $element['mapbox']['#attached']['js'][] = array(
+    'data' => array('geolocation' => $data),
+    'type' => 'setting',
+  );
+
+  $element['field_type'] = array('#type' => 'value', '#value' => $field['type']);
+  $element['#element_validate'] = array('geolocation_mapbox_field_widget_validate');
+  $element['#element_validate'][] = 'geolocation_mapbox_field_widget_set_value';
+
+  return $element;
+}
+
+/**
+ * Implements hook_field_widget_error().
+ */
+function geolocation_mapbox_field_widget_error($element, $error, $form, &$form_state) {
+  switch ($error['error']) {
+    case 'geolocation_invalid_lat':
+    case 'geolocation_invalid_lng':
+      form_error($element, $error['message']);
+      break;
+  }
+}
+
+/**
+ * Implements hook_field_widget_form_alter().
+ */
+function geolocation_mapbox_field_widget_form_alter(&$element, &$form_state, $context) {
+  // Attaches widget JS to each media reference widget.
+  if (isset($element['#type']) && $element['#type'] == 'media') {
+    geolocation_mapbox_attach_mapbox_assets($element);
+  }
+}
+
+/**
+ * Validation handler for geolocation_mapbox_field_widget_form().
+ */
+function geolocation_mapbox_field_widget_validate($element, &$form_state, $form) {
+  if ($element['#required']) {
+    if (!$element['lat']['#value'] || !$element['lng']['#value']) {
+      form_error($element, t('!name field is required.', array('!name' => $element['#title'])));
+    }
+  }
+  else {
+    switch (TRUE) {
+      case $element['lng']['#value'] && !$element['lat']['#value']:
+        form_error($element, t('!name field is incomplete, latitude value is missing.', array('!name' => $element['#title'])));
+        break;
+
+      case !$element['lng']['#value'] && $element['lat']['#value']:
+        form_error($element, t('!name field is incomplete, longitude value is missing.', array('!name' => $element['#title'])));
+        break;
+    }
+  }
+}
+
+/**
+ * Validation handler for Geofield settings.
+ */
+function geolocation_mapbox_field_widget_set_value($element, &$form_state, $form) {
+  $values = &drupal_array_get_nested_value($form_state['values'], $element['#parents']);
+  if ($values['field_type'] == 'geofield') {
+    // Geofield needs the values in their own format which is exactly what
+    // geofield_compute_values does, but we have to change first the longitude
+    // key because geofield uses a different one.
+    $values['lon'] = $values['lng'];
+    $values = geofield_compute_values($values);
+  }
+}
+
+/**
+ * Menu callback for the admin settings.
+ */
+function geolocation_mapbox_admin_settings() {
+  $form['geolocation_mapbox_access_token'] = array(
+    '#title' => t('Your Mapbox Access Token'),
+    '#type' => 'textfield',
+    '#default_value' => variable_get('geolocation_mapbox_access_token', ''),
+    '#size' => 120,
+    '#maxlength' => 255,
+    '#description' => t('An API access token is required to use Mapbox.js. See !token_link.', array('!token_link' => l('https://www.mapbox.com/mapbox.js/api/v2.2.3/api-access-tokens/', 'https://www.mapbox.com/mapbox.js/api/v2.2.3/api-access-tokens/'))),
+  );
+
+  return system_settings_form($form);
+}
+
+/**
+ * Helper function that attaches JS to the given element.
+ * @param array $element
+ */
+function geolocation_mapbox_attach_mapbox_assets(&$element) {
+  $js_added_already = &drupal_static(__FUNCTION__, FALSE);
+  if (!$js_added_already) {
+    $element['#attached']['js'][] = array(
+      'data' => '//api.mapbox.com/mapbox.js/v2.2.3/mapbox.js',
+      'type' => 'external',
+    );
+    $element['#attached']['css'][] = array(
+      'data' => '//api.mapbox.com/mapbox.js/v2.2.3/mapbox.css',
+      'type' => 'external',
+    );
+    $js_added_already = TRUE;
+  }
+}
diff --git a/modules/geolocation_mapbox/geolocation_mapbox_widget.js b/modules/geolocation_mapbox/geolocation_mapbox_widget.js
new file mode 100644
index 0000000..cbb7413
--- /dev/null
+++ b/modules/geolocation_mapbox/geolocation_mapbox_widget.js
@@ -0,0 +1,165 @@
+/**
+ * @file
+ * Javascript for Mapbox widget of Geolocation field.
+ */
+
+(function ($) {
+  var geocoder;
+  Drupal.geolocation = Drupal.geolocation || {};
+  Drupal.geolocation.maps = Drupal.geolocation.maps || {};
+  Drupal.geolocation.markers = Drupal.geolocation.markers || {};
+
+  /**
+   * Set the latitude and longitude values to the input fields
+   * And optionaly update the address field
+   *
+   * @param lat
+   *   the latitude of the marker
+   * @param lng
+   *   the longitude of the marker
+   * @param i
+   *   the index from the maps array we are working on
+   * @param op
+   *   the op that was performed
+   */
+  Drupal.geolocation.codeLatLng = function(lat, lng, i, op) {
+    // Update the lat and lng input fields
+    $('#geolocation-lat-' + i + ' input').attr('value', lat);
+    $('#geolocation-lat-item-' + i + ' .geolocation-lat-item-value').html(lat);
+    $('#geolocation-lng-' + i + ' input').attr('value', lng);
+    $('#geolocation-lng-item-' + i + ' .geolocation-lat-item-value').html(lng);
+
+    // Update the address field
+    if ((op == 'marker' || op == 'geocoder') && geocoder) {
+      geocoder.reverseQuery({ 'lat': lat, 'lng': lng }, function (err, data) {
+        if (data.features) {
+          $('#geolocation-address-' + i + ' input').val(data.features[0].place_name);
+        }
+      });
+    }
+  };
+
+  /**
+   * Get the location from the address field
+   *
+   * @param i
+   *   the index from the maps array we are working on
+   */
+  Drupal.geolocation.codeAddress = function(i) {
+    var address = $('#geolocation-address-' + i + ' input').val();
+
+    geocoder.query(address, function (err, data) {
+      // The geocoder can return an area, like a city, or a
+      // point, like an address. Here we handle both cases,
+      // by fitting the map bounds to an area or zooming to a point.
+      Drupal.geolocation.setMapMarker(data.latlng[0], data.latlng[1], i);
+      Drupal.geolocation.codeLatLng(data.latlng[0], data.latlng[1], i, 'textinput');
+      if (data.lbounds) {
+        Drupal.geolocation.maps[i].fitBounds(data.lbounds);
+      }
+    });
+  };
+
+  /**
+   * Set/Update a marker on a map
+   *
+   * @param lat
+   *   the latitude of the marker
+   * @param lng
+   *   the longitude of the marker
+   * @param i
+   *   the index from the maps array we are working on
+   */
+  Drupal.geolocation.setMapMarker = function(lat, lng, i) {
+    // remove old marker
+    if (Drupal.geolocation.markers[i]) {
+      Drupal.geolocation.maps[i].removeLayer(Drupal.geolocation.markers[i]);
+    }
+
+    Drupal.geolocation.markers[i] = L.marker(new L.LatLng(lat, lng), {
+      icon: L.mapbox.marker.icon({
+        'marker-color': '#000',
+        'marker-symbol': 'star-stroked'
+      }),
+      draggable: Drupal.settings.geolocation.settings.marker_draggable ? true : false
+    });
+
+    Drupal.geolocation.markers[i].addTo(Drupal.geolocation.maps[i]);
+    Drupal.geolocation.maps[i].addLayer(Drupal.geolocation.markers[i]);
+
+    Drupal.geolocation.maps[i].setView([lat, lng]);
+
+    Drupal.geolocation.markers[i].on('dragend', function() {
+      var m = Drupal.geolocation.markers[i].getLatLng();
+      Drupal.geolocation.setMapMarker(m.lat, m.lng, i);
+      Drupal.geolocation.codeLatLng(m.lat, m.lng, i, 'marker');
+    });
+
+    return false; // if called from <a>-Tag
+  };
+
+  /**
+   * Clear/Remove the values and the marker
+   *
+   * @param i
+   *   the index from the maps array we are working on
+   */
+  Drupal.geolocation.clearLocation = function(i) {
+    $('#geolocation-lat-' + i + ' input').attr('value', '');
+    $('#geolocation-lat-item-' + i + ' .geolocation-lat-item-value').html('');
+    $('#geolocation-lng-' + i + ' input').attr('value', '');
+    $('#geolocation-lng-item-' + i + ' .geolocation-lat-item-value').html('');
+    $('#geolocation-address-' + i + ' input').attr('value', '');
+    Drupal.geolocation.maps[i].removeLayer(Drupal.geolocation.markers[i]);
+  };
+
+  Drupal.behaviors.geolocationMapbox = {
+    attach: function(context, settings) {
+      L.mapbox.accessToken = settings.geolocation.settings.accessToken;
+      geocoder = L.mapbox.geocoder('mapbox.places');
+
+      var lat;
+      var lng;
+
+      // Work on each map
+      $.each(settings.geolocation.defaults, function(i, mapDefaults) {
+        $("#geolocation-map-" + i).once('geolocation-mapbox', function() {
+          // Attach listeners.
+          $('#geolocation-address-' + i + ' input').keypress(function(ev) {
+            if (ev.which == 13) {
+              ev.preventDefault();
+              Drupal.geolocation.codeAddress(i);
+            }
+          });
+          $('#geolocation-address-geocode-' + i).click(function(e) {
+            Drupal.geolocation.codeAddress(i);
+          });
+
+          $('#geolocation-remove-' + i).click(function(e) {
+            Drupal.geolocation.clearLocation(i);
+          });
+        });
+
+        // Get default values.
+        lat = $('#geolocation-lat-' + i + ' input').attr('value') == false ? mapDefaults.lat : $('#geolocation-lat-' + i + ' input').attr('value');
+        lng = $('#geolocation-lng-' + i + ' input').attr('value') == false ? mapDefaults.lng : $('#geolocation-lng-' + i + ' input').attr('value');
+
+        // Create map.
+        Drupal.geolocation.maps[i] = L.mapbox.map('geolocation-map-' + i, 'mapbox.streets');
+
+        // Scroll wheel to zoom - defaults to be disabled.
+        Drupal.geolocation.maps[i].scrollWheelZoom.disable();
+        if (Drupal.settings.geolocation.settings.scrollwheel != undefined && Drupal.settings.geolocation.settings.scrollwheel) {
+          Drupal.geolocation.maps[i].scrollWheelZoom.enable();
+        }
+
+        if (lat && lng) {
+          // Set initial marker.
+          Drupal.geolocation.maps[i].setView([lat, lng], 16);
+          Drupal.geolocation.setMapMarker(lat, lng, i);
+          Drupal.geolocation.codeLatLng(lat, lng, i, 'geocoder');
+        }
+      });
+    }
+  };
+})(jQuery);
