diff --git a/geocoder.widget.inc b/geocoder.widget.inc
index 63c8e95..bafe001 100644
--- a/geocoder.widget.inc
+++ b/geocoder.widget.inc
@@ -13,6 +13,15 @@ function geocoder_field_widget_info() {
         'default value' => FIELD_BEHAVIOR_NONE,
       ),
     ),
+    'geocoder_tokens' => array(
+      'label' => t('Geocode from tokens'),
+      'field types' => array('geofield'),
+      'settings' => array('geocoder_tokens' => '[node:title]'),
+      'behaviors' => array(
+        'multiple values' => FIELD_BEHAVIOR_CUSTOM,
+        'default value' => FIELD_BEHAVIOR_NONE,
+      ),
+    ),
   );
 }
 
@@ -67,14 +76,28 @@ function geocoder_field_widget_settings_form($this_field, $instance) {
     }
   }
 
-  $form['geocoder_field'] = array(
-    '#type' => 'select',
-    '#title' => t('Geocode from field'),
-    '#default_value' => isset($settings['geocoder_field']) ? $settings['geocoder_field']: '',
-    '#options' => $valid_fields,
-    '#description' => t('Select which field you would like to geocode from.'),
-    '#required' => TRUE,
-  );
+  switch ($instance['widget']['type']) {
+    case 'geocoder':
+      $form['geocoder_field'] = array(
+        '#type' => 'select',
+        '#title' => t('Geocode from field'),
+        '#default_value' => isset($settings['geocoder_field']) ? $settings['geocoder_field']: '',
+        '#options' => $valid_fields,
+        '#description' => t('Select which field you would like to geocode from.'),
+        '#required' => TRUE,
+      );
+      break;
+
+    case 'geocoder_tokens':
+      $form['geocoder_tokens'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Geocode from tokens'),
+        '#default_value' => $settings['geocoder_tokens'],
+        '#description' => t("Use this entity's tokens to create a location string that the handler will understand. It will be evaluated for every item (for multiple value fields)."),
+        '#required' => TRUE,
+      );
+      break;
+  }
 
   $form['geocoder_handler'] = array(
     '#type' => 'select',
@@ -157,7 +180,62 @@ function geocoder_field_attach_presave($entity_type, $entity) {
         $entity->{$field_instance['field_name']} = $field_value;
       }
     }
+    elseif ($field_instance['widget']['type'] === 'geocoder_tokens') {
+      if (($field_value = geocoder_widget_get_token_value($entity_type, $field_instance, $entity)) !== FALSE) {
+        $entity->{$field_instance['field_name']} = $field_value;
+      }
+    }
+  }
+}
+
+/**
+ * Geocode from the entire entity's tokens, not 1 source field.
+ */
+function geocoder_widget_get_token_value($entity_type, $field_instance, $entity) {
+  list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
+  $entity = clone $entity;
+  $instances = field_info_instances($entity_type, $bundle);
+
+  $values = array();
+  for ($i=0; $i<20; $i++) {
+    $value = token_replace($field_instance['widget']['settings']['geocoder_tokens'], array(
+      $entity_type => $entity,
+    ));
+    if ($value && !in_array($value, $values)) {
+      $values[] = $value;
+    }
+
+    foreach ($instances as $field_name => $foo) {
+      foreach ($entity->$field_name as $langcode => &$items) {
+        if ($items) {
+          $shifted = array_shift($items);
+        }
+
+        unset($items);
+      }
+    }
   }
+
+  // Last item will have been valueless.
+  array_pop($values);
+
+  $field_info = array('type' => 'text', 'entity_key' => FALSE);
+  $handler = geocoder_get_handler($field_instance['widget']['settings']['geocoder_handler']);
+  $handler_settings = @$field_instance['widget']['settings']['handler_settings'][$handler['name']] ?: array();
+
+  $geometries = array();
+  foreach ($values as $value) {
+    $item = compact('value');
+    $geometries[] = call_user_func($handler['field_callback'], $field_info, $item, $handler_settings);
+  }
+
+  $delta_handling = @$field_instance['widget']['settings']['delta_handling'] ?: 'default';
+  $target_info = field_info_field($field_instance['field_name']);
+  $target_type = $target_info['type'];
+
+  $items = geocoder_widget_resolve_deltas(array_filter($geometries), $delta_handling, $target_type);
+  dpm($items, 'items');
+  return array(LANGUAGE_NONE => $items);
 }
 
 /**
