diff --git a/link.module b/link.module
index 9e52de5..b9a6616 100644
--- a/link.module
+++ b/link.module
@@ -744,29 +744,67 @@ function theme_link_formatter_link_separate($vars) {
   return $output;
 }
 
+/**
+ * Implements hook_token_info().
+ */
+function link_token_info() {
+  $info['types']['link-field-field'] = array(
+    'name' => t('Link fields'),
+    'description' => t('Tokens related to link field instances.'),
+    'needs-data' => 'link-field-field',
+    'field' => TRUE,
+    'module' => 'link',
+  );
+  $info['types']['link-field-field-value'] = array(
+    'name' => t('Link field values'),
+    'description' => t('Tokens related to link field values.'),
+    'needs-data' => 'link-field-field-value',
+    'field-value' => TRUE,
+    'module' => 'link',
+  );
 
-function link_token_list($type = 'all') {
-  if ($type === 'field' || $type === 'all') {
-    $tokens = array();
-
-    $tokens['link']['url'] = t("Link URL");
-    $tokens['link']['title'] = t("Link title");
-    $tokens['link']['view'] = t("Formatted html link");
+  $info['tokens']['link-field-field-value']['link'] = array(
+    'name' => t('Link'),
+    'description' => t('The formatted HTML link.'),
+  );
+  $info['tokens']['link-field-field-value']['title'] = array(
+    'name' => t('Title'),
+    'description' => t('The link title.'),
+  );
+  $info['tokens']['link-field-field-value']['url'] = array(
+    'name' => t('URL'),
+    'description' => t('The link URL.'),
+  );
 
-    return $tokens;
-  }
+  return $info;
 }
 
-function link_token_values($type, $object = NULL) {
-  if ($type === 'field') {
-    $item = $object[0];
+/**
+ * Implements hook_tokens().
+ */
+function link_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $replacements = array();
+  $sanitize = !empty($options['sanitize']);
 
-    $tokens['url'] = $item['url'];
-    $tokens['title'] = $item['title'];
-    $tokens['view'] = isset($item['view']) ? $item['view'] : '';
+  if ($type == 'link-field-field-value' && !empty($data['item'])) {
+    $item = $data['item'];
 
-    return $tokens;
+    foreach ($tokens as $name => $original) {
+      switch ($name) {
+        case 'link':
+          $replacements[$original] = l($item['title'], $item['url']);
+          break;
+        case 'title':
+          $replacements[$original] = $sanitize ? check_plain($item['title']) : $item['title'];
+          break;
+        case 'url':
+          $replacements[$original] = $item['url'];
+          break;
+      }
+    }
   }
+
+  return $replacements;
 }
 
 /**
