diff --git a/gdata/gdata-core.symbols b/gdata/gdata-core.symbols
index c04188d..a4a8d0b 100644
--- a/gdata/gdata-core.symbols
+++ b/gdata/gdata-core.symbols
@@ -45,6 +45,7 @@ gdata_feed_get_rights
 gdata_feed_get_items_per_page
 gdata_feed_get_start_index
 gdata_feed_get_total_results
+gdata_feed_get_next_page_token
 gdata_service_get_type
 gdata_service_error_quark
 gdata_service_query
@@ -1006,6 +1007,8 @@ gdata_tasks_query_get_show_deleted
 gdata_tasks_query_set_show_deleted
 gdata_tasks_query_get_show_hidden
 gdata_tasks_query_set_show_hidden
+gdata_tasks_query_get_page_token
+gdata_tasks_query_set_page_token
 gdata_tasks_service_get_type
 gdata_tasks_service_new
 gdata_tasks_service_get_primary_authorization_domain
diff --git a/gdata/gdata-feed.c b/gdata/gdata-feed.c
index cfcbe39..50fe428 100644
--- a/gdata/gdata-feed.c
+++ b/gdata/gdata-feed.c
@@ -78,6 +78,7 @@ struct _GDataFeedPrivate {
 	guint start_index;
 	guint total_results;
 	gchar *rights;
+	gchar *next_page_token;
 };
 
 enum {
@@ -92,7 +93,8 @@ enum {
 	PROP_ITEMS_PER_PAGE,
 	PROP_START_INDEX,
 	PROP_TOTAL_RESULTS,
-	PROP_RIGHTS
+	PROP_RIGHTS,
+	PROP_NEXT_PAGE_TOKEN
 };
 
 G_DEFINE_TYPE (GDataFeed, gdata_feed, GDATA_TYPE_PARSABLE)
@@ -296,6 +298,20 @@ gdata_feed_class_init (GDataFeedClass *klass)
 	                                                    "Total results", "The total number of results in the feed.",
 	                                                    0, 1000000, 0,
 	                                                    G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataFeed:next-page-token:
+	 *
+	 * The next page token for GTask feeds. Pass this to gdata_tasks_query_set_page_token()
+	 * to advance to the next page when querying tasks.
+	 *
+	 * Since: 0.17.7
+	 **/
+	g_object_class_install_property (gobject_class, PROP_NEXT_PAGE_TOKEN,
+	                                 g_param_spec_string ("next-page-token",
+	                                                      "Next page token", "Token specifying the next page for a GTask query.",
+	                                                      NULL,
+	                                                      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -354,6 +370,7 @@ gdata_feed_finalize (GObject *object)
 	g_free (priv->logo);
 	g_free (priv->icon);
 	g_free (priv->rights);
+	g_free (priv->next_page_token);
 
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_feed_parent_class)->finalize (object);
@@ -401,6 +418,9 @@ gdata_feed_get_property (GObject *object, guint property_id, GValue *value, GPar
 		case PROP_TOTAL_RESULTS:
 			g_value_set_uint (value, priv->total_results);
 			break;
+		case PROP_NEXT_PAGE_TOKEN:
+			g_value_set_string (value, priv->next_page_token);
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -642,6 +662,8 @@ parse_json (GDataParsable *parsable, JsonReader *reader, gpointer user_data, GEr
 		/* Ignore. */
 	} else if (g_strcmp0 (json_reader_get_member_name (reader), "etag") == 0) {
 		GDATA_FEED (parsable)->priv->etag = g_strdup (json_reader_get_string_value (reader));
+	} else if (g_strcmp0 (json_reader_get_member_name (reader), "nextPageToken") == 0) {
+		GDATA_FEED (parsable)->priv->next_page_token = g_strdup (json_reader_get_string_value (reader));
 	} else {
 		return GDATA_PARSABLE_CLASS (gdata_feed_parent_class)->parse_json (parsable, reader, user_data, error);
 	}
@@ -1071,6 +1093,23 @@ gdata_feed_get_total_results (GDataFeed *self)
 	return self->priv->total_results;
 }
 
+/**
+ * gdata_feed_get_next_page_token:
+ * @self: a #GDataFeed
+ *
+ * Returns the next page token for a GTask query result, or %NULL if not set.
+ *
+ * Return value: the next page token
+ *
+ * Since: 0.17.7
+ **/
+const gchar *
+gdata_feed_get_next_page_token (GDataFeed *self)
+{
+	g_return_val_if_fail (GDATA_IS_FEED (self), NULL);
+	return self->priv->next_page_token;
+}
+
 void
 _gdata_feed_add_entry (GDataFeed *self, GDataEntry *entry)
 {
diff --git a/gdata/gdata-feed.h b/gdata/gdata-feed.h
index c94431f..3104fbb 100644
--- a/gdata/gdata-feed.h
+++ b/gdata/gdata-feed.h
@@ -90,6 +90,7 @@ guint gdata_feed_get_items_per_page (GDataFeed *self) G_GNUC_PURE;
 guint gdata_feed_get_start_index (GDataFeed *self) G_GNUC_PURE;
 guint gdata_feed_get_total_results (GDataFeed *self) G_GNUC_PURE;
 const gchar *gdata_feed_get_icon (GDataFeed *self) G_GNUC_PURE;
+const gchar *gdata_feed_get_next_page_token (GDataFeed *self) G_GNUC_PURE;
 
 G_END_DECLS
 
diff --git a/gdata/services/tasks/gdata-tasks-query.c b/gdata/services/tasks/gdata-tasks-query.c
index 9e6dbd9..91ec459 100644
--- a/gdata/services/tasks/gdata-tasks-query.c
+++ b/gdata/services/tasks/gdata-tasks-query.c
@@ -54,6 +54,7 @@ struct _GDataTasksQueryPrivate {
 	gboolean show_completed;
 	gboolean show_deleted;
 	gboolean show_hidden;
+	gchar *page_token;
 };
 
 enum {
@@ -64,6 +65,7 @@ enum {
 	PROP_SHOW_COMPLETED,
 	PROP_SHOW_DELETED,
 	PROP_SHOW_HIDDEN,
+	PROP_PAGE_TOKEN
 };
 
 G_DEFINE_TYPE (GDataTasksQuery, gdata_tasks_query, GDATA_TYPE_QUERY)
@@ -175,6 +177,19 @@ gdata_tasks_query_class_init (GDataTasksQueryClass *klass)
 	                                 "Show hidden tasks?", "Indicated whatever hidden tasks are returned in the result.",
 	                                 FALSE,
 	                                 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataTasksQuery:page-token:
+	 *
+	 * Token specifying the result page to return. Optional. The default is to return the first page.
+	 *
+	 * Since: 0.17.7
+	 */
+	g_object_class_install_property (gobject_class, PROP_PAGE_TOKEN,
+	                                 g_param_spec_string ("page-token",
+	                                 "Page token", "Page token specifying which page to return.",
+	                                 NULL,
+	                                 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -185,11 +200,16 @@ gdata_tasks_query_init (GDataTasksQuery *self)
 	self->priv->completed_max = -1;
 	self->priv->due_min = -1;
 	self->priv->due_max = -1;
+	self->priv->page_token = NULL;
 }
 
 static void
 gdata_tasks_query_finalize (GObject *object)
 {
+	GDataTasksQuery *self = GDATA_TASKS_QUERY (object);
+
+	g_free (self->priv->page_token);
+
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_tasks_query_parent_class)->finalize (object);
 }
@@ -221,6 +241,9 @@ gdata_tasks_query_get_property (GObject *object, guint property_id, GValue *valu
 		case PROP_SHOW_HIDDEN:
 			g_value_set_boolean (value, priv->show_hidden);
 			break;
+		case PROP_PAGE_TOKEN:
+			g_value_set_string (value, priv->page_token);
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -255,6 +278,9 @@ gdata_tasks_query_set_property (GObject *object, guint property_id, const GValue
 		case PROP_SHOW_HIDDEN:
 			gdata_tasks_query_set_show_hidden (self, g_value_get_boolean (value));
 			break;
+		case PROP_PAGE_TOKEN:
+			gdata_tasks_query_set_page_token (self, g_value_get_string (value));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -274,6 +300,11 @@ get_query_uri (GDataQuery *self, const gchar *feed_uri, GString *query_uri, gboo
 		g_string_append_printf (query_uri, "maxResults=%u", gdata_query_get_max_results (GDATA_QUERY (self)));
 	}
 
+	if (priv->page_token && *priv->page_token) {
+		APPEND_SEP
+		g_string_append_printf (query_uri, "pageToken=%s", priv->page_token);
+	}
+
 	if (gdata_query_get_updated_min (GDATA_QUERY (self)) != -1) {
 		gchar *updated_min;
 
@@ -651,3 +682,48 @@ gdata_tasks_query_set_show_hidden (GDataTasksQuery *self, gboolean show_hidden)
 	/* Our current ETag will no longer be relevant. */
 	gdata_query_set_etag (GDATA_QUERY (self), NULL);
 }
+
+/**
+ * gdata_tasks_query_get_page_token:
+ * @self: a #GDataTasksQuery
+ *
+ * Gets the #GDataTasksQuery:page-token property.
+ *
+ * Return value: the page-token property
+ *
+ * Since: 0.17.7
+ */
+const gchar *
+gdata_tasks_query_get_page_token (GDataTasksQuery *self)
+{
+	g_return_val_if_fail (GDATA_IS_TASKS_QUERY (self), NULL);
+	return self->priv->page_token;
+}
+
+/**
+ * gdata_tasks_query_set_page_token:
+ * @self: a #GDataTasksQuery
+ * @page_token: (nullable): a page token, or %NULL
+ *
+ * Sets the #GDataTasksQuery:page-token property of the #GDataTasksQuery.
+ *
+ * Since: 0.17.7
+ */
+void
+gdata_tasks_query_set_page_token (GDataTasksQuery *self, const gchar *page_token)
+{
+	g_return_if_fail (GDATA_IS_TASKS_QUERY (self));
+
+	if (page_token && !*page_token)
+		page_token = NULL;
+
+	if (g_strcmp0 (self->priv->page_token, page_token) == 0)
+		return;
+
+	g_free (self->priv->page_token);
+	self->priv->page_token = g_strdup (page_token);
+	g_object_notify (G_OBJECT (self), "page-token");
+
+	/* Our current ETag will no longer be relevant. */
+	gdata_query_set_etag (GDATA_QUERY (self), NULL);
+}
diff --git a/gdata/services/tasks/gdata-tasks-query.h b/gdata/services/tasks/gdata-tasks-query.h
index bb399d9..0e3511c 100644
--- a/gdata/services/tasks/gdata-tasks-query.h
+++ b/gdata/services/tasks/gdata-tasks-query.h
@@ -84,6 +84,8 @@ gboolean gdata_tasks_query_get_show_deleted (GDataTasksQuery *self) G_GNUC_PURE;
 void gdata_tasks_query_set_show_deleted (GDataTasksQuery *self, gboolean show_deleted);
 gboolean gdata_tasks_query_get_show_hidden (GDataTasksQuery *self) G_GNUC_PURE;
 void gdata_tasks_query_set_show_hidden (GDataTasksQuery *self, gboolean show_hidden);
+const gchar *gdata_tasks_query_get_page_token (GDataTasksQuery *self) G_GNUC_PURE;
+void gdata_tasks_query_set_page_token (GDataTasksQuery *self, const gchar *page_token);
 
 G_END_DECLS
 
