diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index 7633c3a..fc3333f 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -221,6 +221,11 @@ struct _EvView {
 	gboolean cursor_visible;
 	guint    cursor_blink_timeout_id;
 	guint    cursor_blink_time;
+
+	/* Field tab navigation */
+	GList *form_field_order;
+	gint form_field_current;
+	gboolean form_field_focused;
 };
 
 struct _EvViewClass {
diff --git a/libview/ev-view.c b/libview/ev-view.c
index da69022..fa045bf 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -134,6 +134,11 @@ static char*      tip_from_link                              (EvView
 static EvFormField *ev_view_get_form_field_at_location       (EvView             *view,
 							       gdouble            x,
 							       gdouble            y);
+static gboolean
+ev_view_form_key_press                                       (GtkWidget          *widget,
+									GdkEventKey       *event,
+									EvView            *view);
+
 
 /*** Annotations ***/
 static EvAnnotation *ev_view_get_annotation_at_location      (EvView             *view,
@@ -183,6 +188,9 @@ static void       highlight_find_results                     (EvView
 static void       highlight_forward_search_results           (EvView             *view,
                                                               cairo_t            *cr,
 							      int                 page);
+static void       highlight_form_field                       (EvView             *view,
+                                                              cairo_t            *cr);
+
 static void       draw_one_page                              (EvView             *view,
 							      gint                page,
 							      cairo_t            *cr,
@@ -2262,19 +2270,41 @@ ev_view_form_field_button_toggle (EvView      *view,
 	cairo_region_destroy (region);
 }
 
+static void
+ev_view_form_button_toggled (GtkButton *button, EvView *view)
+{
+	EvFormField *field;
+
+	if (!view->document)
+		return;
+
+	field = g_object_get_data (G_OBJECT (button), "form-field");
+	ev_view_form_field_button_toggle (view, field);
+	if (field->activation_link)
+		ev_view_handle_link (view, field->activation_link);
+}
+
 static GtkWidget *
 ev_view_form_field_button_create_widget (EvView      *view,
 					 EvFormField *field)
 {
 	EvMappingList *form_mapping;
 	EvMapping     *mapping;
+	GtkWidget *button = NULL;
 
 	form_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
 							     field->page->index);
 	mapping = ev_mapping_list_find (form_mapping, field);
 	ev_view_set_focused_element (view, mapping, field->page->index);
 
-	return NULL;
+	button = gtk_button_new ();
+	g_signal_connect (button, "clicked",
+				G_CALLBACK (ev_view_form_button_toggled),
+				view);
+	g_signal_connect (button, "key_press_event",
+				G_CALLBACK (ev_view_form_key_press),
+				view);
+	return button;
 }
 
 static void
@@ -2371,6 +2401,9 @@ ev_view_form_field_text_create_widget (EvView      *view,
 			g_signal_connect_after (text, "activate",
 						G_CALLBACK (ev_view_form_field_destroy),
 						view);
+			g_signal_connect (text, "key_press_event",
+						G_CALLBACK (ev_view_form_key_press),
+						view);
 			break;
 	        case EV_FORM_FIELD_TEXT_MULTILINE: {
 			GtkTextBuffer *buffer;
@@ -2389,6 +2422,10 @@ ev_view_form_field_text_create_widget (EvView      *view,
 			g_signal_connect (buffer, "changed",
 					  G_CALLBACK (ev_view_form_field_text_changed),
 					  field);
+			g_signal_connect (text, "key_press_event",
+						G_CALLBACK (ev_view_form_key_press),
+						view);
+
 		}
 			break;
 	}			
@@ -2563,6 +2600,9 @@ ev_view_form_field_choice_create_widget (EvView      *view,
 		g_signal_connect_after (selection, "changed",
 					G_CALLBACK (ev_view_form_field_destroy),
 					view);
+		g_signal_connect (selection, "key_press_event",
+					G_CALLBACK (ev_view_form_key_press),
+					view);
 	} else if (field_choice->is_editable) { /* ComboBoxEntry */
 		gchar *text;
 
@@ -2582,6 +2622,9 @@ ev_view_form_field_choice_create_widget (EvView      *view,
 					"activate",
 					G_CALLBACK (ev_view_form_field_destroy),
 					view);
+		g_signal_connect (choice, "key_press_event",
+					G_CALLBACK (ev_view_form_key_press),
+					view);
 	} else { /* ComboBoxText */
 		GtkCellRenderer *renderer;
 
@@ -2602,6 +2645,9 @@ ev_view_form_field_choice_create_widget (EvView      *view,
 		g_signal_connect_after (choice, "changed",
 					G_CALLBACK (ev_view_form_field_destroy),
 					view);
+		g_signal_connect (choice, "key_press_event",
+					G_CALLBACK (ev_view_form_key_press),
+					view);
 	}
 
 	g_object_unref (model);
@@ -2614,12 +2660,19 @@ ev_view_form_field_choice_create_widget (EvView      *view,
 }
 
 static void
+field_widget_destroy (GtkWidget *object, EvView *view) {
+	view->form_field_focused = FALSE;
+}
+
+static void
 ev_view_focus_form_field (EvView      *view,
 			  EvFormField *field)
 {
 	GtkWidget     *field_widget = NULL;
 	EvMappingList *form_field_mapping;
 	EvMapping     *mapping;
+	GtkStyleContext *context;
+	GdkRGBA          color;
 
 	ev_view_set_focused_element (view, NULL, -1);
 
@@ -2640,6 +2693,19 @@ ev_view_focus_form_field (EvView      *view,
 	if (!field_widget)
 		return;
 
+	/* Highlight focused fields */
+	context = gtk_widget_get_style_context (GTK_WIDGET (view));
+	gtk_style_context_get_background_color (context, GTK_STATE_FLAG_SELECTED, &color);
+	if (EV_IS_FORM_FIELD_BUTTON (field))
+		color.alpha = 0.0;
+
+	gtk_widget_override_background_color (field_widget, GTK_STATE_FLAG_NORMAL, &color);
+	view->form_field_focused = TRUE;
+
+	g_signal_connect (field_widget, "destroy",
+			G_CALLBACK (field_widget_destroy),
+			view);
+
 	g_object_set_data_full (G_OBJECT (field_widget), "form-field",
 				g_object_ref (field),
 				(GDestroyNotify)g_object_unref);
@@ -2659,14 +2725,83 @@ ev_view_handle_form_field (EvView      *view,
 	if (field->is_read_only)
 		return;
 
+	if (EV_IS_FORM_FIELD_BUTTON (field))
+		ev_view_form_field_button_toggle (view, field);
+
 	ev_view_focus_form_field (view, field);
 
 	if (field->activation_link)
 		ev_view_handle_link (view, field->activation_link);
 
-	if (EV_IS_FORM_FIELD_BUTTON (field))
-		ev_view_form_field_button_toggle (view, field);
+}
 
+static gboolean
+ev_view_form_key_press (GtkWidget *widget, GdkEventKey *event, EvView *view)
+{
+	EvFormField *field;
+	switch (event->keyval) {
+		case GDK_KEY_ISO_Left_Tab:
+		case GDK_KEY_Tab:
+			if (event->state & GDK_SHIFT_MASK) {
+				view->form_field_current++;
+				if (view->form_field_current == g_list_length (view->form_field_order))
+					view->form_field_current = 0;
+			} else {
+				view->form_field_current--;
+				if (view->form_field_current < 0)
+					view->form_field_current = g_list_length (view->form_field_order) - 1;
+			}
+			field = EV_FORM_FIELD(g_list_nth_data (view->form_field_order, view->form_field_current));
+			ev_view_remove_all (view);
+			ev_view_focus_form_field (view, field);
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static GList*
+page_form_field_order (EvView *view, guint page) {
+	EvMappingList *mappings = ev_page_cache_get_form_field_mapping (view->page_cache, page);
+	GList *list;
+	GList *order = NULL;
+
+	if (!mappings)
+		return NULL;
+
+	/* use structure order */
+	for (list = ev_mapping_list_get_list(mappings); list; list = list->next) {
+		EvMapping *mapping = list->data;
+		EvFormField *field = mapping->data;
+		/*
+		   ignore read-only fields
+		   ignore signature fields (until they are implemented)
+		*/
+		if (!field->is_read_only && !EV_IS_FORM_FIELD_SIGNATURE(field))
+			order = g_list_append (order, field);
+	}
+	return order;
+}
+
+static void
+create_form_field_order (EvView *view) {
+	GList *order = NULL;
+	guint page;
+	if (!EV_IS_DOCUMENT_FORMS (view->document))
+		return;
+
+	guint n_pages = ev_document_get_n_pages (view->document);
+	for (page = 0; page < n_pages; page++) {
+		GList *list = page_form_field_order (view, page);
+		order = g_list_concat (order, list);
+	}
+	view->form_field_order = order;
+	view->form_field_current = -1;
+	view->form_field_focused = FALSE;
+}
+
+static void
+set_form_field_current (EvView *view, EvFormField *field) {
+	view->form_field_current = g_list_index (view->form_field_order, field);
 }
 
 /* Annotations */
@@ -4255,6 +4390,8 @@ ev_view_draw (GtkWidget *widget,
 			draw_focus (view, cr, i, &clip_rect);
 		if (page_ready && view->synctex_result)
 			highlight_forward_search_results (view, cr, i);
+		if (page_ready && view->form_field_focused)
+			highlight_form_field (view, cr);
 #ifdef EV_ENABLE_DEBUG
 		if (page_ready)
 			draw_debug_borders (view, cr, i, &clip_rect);
@@ -4671,6 +4808,10 @@ ev_view_button_press_event (GtkWidget      *widget,
 			} else if ((field = ev_view_get_form_field_at_location (view, event->x, event->y))) {
 				ev_view_remove_all (view);
 				ev_view_handle_form_field (view, field);
+				if (!view->form_field_order)
+					create_form_field_order (view);
+
+				set_form_field_current (view, field);
 			} else if ((link = get_link_mapping_at_location (view, event->x, event->y, &page))){
 				ev_view_set_focused_element (view, link, page);
 			} else if (!location_in_text (view, event->x + view->scroll_x, event->y + view->scroll_y) &&
@@ -5710,11 +5851,6 @@ ev_view_activate_form_field (EvView      *view,
 		handled = TRUE;
 	}
 
-	if (EV_IS_FORM_FIELD_BUTTON (field)) {
-		ev_view_form_field_button_toggle (view, field);
-		handled = TRUE;
-	}
-
 	return handled;
 }
 
@@ -5911,6 +6047,26 @@ highlight_forward_search_results (EvView *view,
 }
 
 static void
+highlight_form_field (EvView *view,
+					  cairo_t *cr)
+{
+	GdkRectangle rect;
+	EvMappingList *form_field_mapping;
+	EvMapping     *mapping;
+	EvFormField *field = EV_FORM_FIELD (g_list_nth_data (view->form_field_order, view->form_field_current));
+
+	/* We let text field widgets highlight on their own (via background color) */
+	if (EV_IS_FORM_FIELD_TEXT (field))
+		return;
+
+	form_field_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
+								   field->page->index);
+	mapping = ev_mapping_list_find (form_field_mapping, field);
+	_ev_view_transform_doc_rect_to_view_rect (view, field->page->index, &mapping->area, &rect);
+	draw_rubberband (view, cr, &rect, 0.6);
+}
+
+static void
 draw_surface (cairo_t 	      *cr,
 	      cairo_surface_t *surface,
 	      gint             x,
@@ -6676,6 +6832,9 @@ ev_view_init (EvView *view)
 	view->pixbuf_cache_size = DEFAULT_PIXBUF_CACHE_SIZE;
 	view->caret_enabled = FALSE;
 	view->cursor_page = 0;
+	view->form_field_order = NULL;
+	view->form_field_current = -1;
+	view->form_field_focused = FALSE;
 }
 
 /*** Callbacks ***/
