diff --git a/link.module b/link.module
index 41d0415..761f850 100644
--- a/link.module
+++ b/link.module
@@ -263,7 +263,7 @@ function link_field_validate($entity_type, $entity, $field, $instance, $langcode
   $optional_field_found = FALSE;
   if ($instance['settings']['validate_url'] !== 0 || is_null($instance['settings']['validate_url']) || !isset($instance['settings']['validate_url'])) {
     foreach ($items as $delta => $value) {
-      _link_validate($items[$delta], $delta, $field, $entity, $instance, $langcode, $optional_field_found);
+      _link_validate($items[$delta], $delta, $field, $entity, $instance, $langcode, $optional_field_found, $errors);
     }
   }
 
@@ -317,6 +317,21 @@ function link_field_widget_form(&$form, &$form_state, $field, $instance, $langco
 }
 
 /**
+ * Implements hook_field_widget_error().
+ */
+function link_field_widget_error($element, $error, $form, &$form_state) {
+  switch ($error['error']) {
+    case 'field_link_invalid_url':
+      form_error($element['url'], $error['message']);
+      break;
+
+    case 'field_link_invalid_title':
+      form_error($element['title'], $error['message']);
+      break;
+  }
+}
+
+/**
  * Unpacks the item attributes for use.
  */
 function _link_load($field, $item, $instance) {
@@ -374,25 +389,34 @@ function _link_process(&$item, $delta = 0, $field, $entity) {
 /**
  * Validates that the link field has been entered properly.
  */
-function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$optional_field_found) {
+function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$optional_field_found, &$errors) {
   if ($item['url']
       && !(isset($instance['default_value'][$delta]['url'])
       && $item['url'] === $instance['default_value'][$delta]['url']
       && !$instance['required'])) {
     // Validate the link.
     if (link_validate_url(trim($item['url'])) == FALSE) {
-      form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][url', t('Not a valid URL.'));
+      $errors[$field['field_name']][$langcode][$delta][] = array(
+        'error' => 'field_link_invalid_url',
+        'message' => t('Not a valid URL.'),
+      );
     }
     // Require a title for the link if necessary.
     if ($instance['settings']['title'] == 'required' && strlen(trim($item['title'])) == 0) {
-      form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][title', t('Titles are required for all links.'));
+      $errors[$field['field_name']][$langcode][$delta][] = array(
+        'error' => 'field_link_invalid_title',
+        'message' => t('Titles are required for all links.'),
+      );
     }
   }
   // Require a link if we have a title.
   if ($instance['settings']['url'] !== 'optional'
       && strlen(isset($item['title']) ? $item['title'] : NULL) > 0
       && strlen(trim($item['url'])) == 0) {
-    form_set_error($field['field_name'] . '][' . $langcode . ']['. $delta .'][url', t('You cannot enter a title without a link url.'));
+    $errors[$field['field_name']][$langcode][$delta][] = array(
+      'error' => 'field_link_invalid_url',
+      'message' => t('You cannot enter a title without a link url.'),
+    );
   }
   // In a totally bizzaro case, where URLs and titles are optional but the field is required, ensure there is at least one link.
   if ($instance['settings']['url'] === 'optional'
@@ -406,8 +430,10 @@ function _link_validate(&$item, $delta, $field, $node, $instance, $langcode, &$o
     && $instance['required'] == 1
     && !$optional_field_found
     && isset($instance['id'])) {
-    form_set_error($instance['field_name'] . '][' . $langcode . '][0][title',
-                   t('At least one title or URL must be entered.'));
+    $errors[$field['field_name']][$langcode][$delta][] = array(
+      'error' => 'field_link_invalid_title',
+      'message' => t('At least one title or URL must be entered.'),
+    );
   }
 }
 
