diff --git a/geocoder.module b/geocoder.module
index 29ab9cf..6a01afa 100644
--- a/geocoder.module
+++ b/geocoder.module
@@ -240,6 +240,9 @@ function geocoder_permission() {
     'geocoder_service_all_handlers' => array(
       'title' => t('Can use all Geocoder handlers through AJAX / service'),
     ),
+    'geocoder_reverse_handler' => array(
+      'title' => t('Can use the Geocoder reverse handler'),
+    ),
   );
   foreach ($handler_info as $name => $handler) {
     $perms['geocoder_service_handler_' . $name] = array(
@@ -399,3 +402,80 @@ function geocoder_cache_set($geometry, $handler, $data, $options) {
 function geocoder_flush_caches() {
   return array('cache_geocoder');
 }
+
+
+/**
+ * Implements hook_entity_info_alter().
+ */
+function geocoder_entity_info_alter(&$info) {
+
+  $fields = geocoder_get_active_geofields();
+
+  if ($fields) {
+    foreach($fields as $field_info) {
+      $entity = $field_info['entity_type'];
+      $bundle = $field_info['bundle'];
+      $field_name = $field_info['field_name'];
+      $info[$entity]['geocoder'][$bundle] = $field_name;
+    }
+  }
+}
+
+function geocoder_get_active_geofields() {
+
+  static $info;
+
+  if (!isset($info)) {
+    $query = db_select('field_config', 'fc', array('fetch' => PDO::FETCH_ASSOC));
+    $query->join('field_config_instance', 'fci', 'fc.id = fci.field_id');
+    $query->fields('fci', array('field_name', 'entity_type', 'bundle'));
+    $query->condition('fc.type', 'geofield', '=');
+    $query->condition('fc.active', 1);
+    $info = $query->execute()->fetchAll();
+  }
+  return $info;
+}
+
+/*
+ * Implementes hook_entity_presave().
+ */
+function geocoder_entity_presave($entity, $entity_type) {
+
+  $info = entity_get_info($entity_type);
+  list(,, $bundle) = entity_extract_ids($entity_type, $entity);
+
+  if (isset($info['geocoder'][$bundle])) {
+    $target_field = $info['geocoder'][$bundle];
+    $instance = field_info_instance($entity_type, $target_field, $bundle);
+    $settings = $instance['widget']['settings'];
+
+    if (isset($settings['geocoder_presave']) ){
+      $source_field = $settings['geocoder_field'];
+      $handler = geocoder_get_handler($settings['geocoder_handler']);
+      $field_values = field_get_items($entity_type, $entity, $source_field);
+      $field_info = field_info_field($source_field);
+      foreach($field_values as $delta => $field_value) {
+
+        if (isset($settings['geocoder_skip_existing_targets']) && $settings['geocoder_skip_existing_targets'] == 1){
+          // If there is already a value dont geocode again.
+          if (!empty($entity->{$target_field}[LANGUAGE_NONE][$delta]['lat'])) {
+            return;
+          }
+        }
+        else {
+          try {
+            $geometry = call_user_func($handler['field_callback'], $field_info, $field_value);
+          }
+          catch(Exception $e) {
+            //$title = $field_value['organisation_name'];
+            drupal_set_message($e->getMessage(), 'error');
+            return;
+          }
+          if ($geometry) {
+            $entity->{$target_field}[LANGUAGE_NONE][$delta] = geofield_get_values_from_geometry($geometry);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/geocoder.widget.inc b/geocoder.widget.inc
index 60ab70d..5091c34 100644
--- a/geocoder.widget.inc
+++ b/geocoder.widget.inc
@@ -28,6 +28,11 @@ function geocoder_field_widget_info() {
         'multiple values' => FIELD_BEHAVIOR_CUSTOM,
         'default value' => FIELD_BEHAVIOR_NONE,
       ),
+      'settings' => array(
+        'geocoder_presave' => 1,
+        'geocoder_field' => '',
+        'geocoder_handler' => '',
+      ),
     ),
   );
 }
@@ -117,6 +122,27 @@ function geocoder_field_widget_settings_form($this_field, $instance) {
   }
 
   natcasesort($valid_fields);
+
+  $form['geocoder_presave'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Geocode on Save'),
+    '#default_value' => isset($settings['geocoder_presave']) ? $settings['geocoder_presave'] : 0,
+    '#options' => array(
+      0 => t('Geocode only on Form Submission'),
+      1 => t('Geocode only on Save'),
+    ),
+    '#description' => t('Select if you want to geocode on any save operation, or only from form submissions.'),
+  );
+  $form['geocoder_skip_existing_targets'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Geocode only empty targets'),
+    '#default_value' => isset($settings['geocoder_skip_existing_targets']) ? $settings['geocoder_skip_existing_targets'] : 0,
+    '#options' => array(
+      0 => t('Geocode existing targets'),
+      1 => t('Geocode only empty targets'),
+    ),
+    '#description' => t('Select if you want to geocode also already geocoded.'),
+  );
   $form['geocoder_field'] = array(
     '#type' => 'select',
     '#title' => t('Geocode from field'),
