diff --git a/apps/include/system/ubgps.h b/apps/include/system/ubgps.h
index 241578491182344c196d7c3862ae4fd7555869b5..a75431bcea7ee2eeff90f0f1ad1c7a33edb6d607 100644
--- a/apps/include/system/ubgps.h
+++ b/apps/include/system/ubgps.h
@@ -499,6 +499,27 @@ int ubgps_set_aiding_params(bool use_time,
                              int32_t altitude,
                              uint32_t accuracy);
 
+/****************************************************************************
+ * Name: ubgps_give_location_hint
+ *
+ * Description:
+ *   Give location hint for A-GPS
+ *
+ * Input Parameters:
+ *   latitude    - Latitude
+ *   longitude   - Longitude
+ *   altitude    - Altitude in meters
+ *   accuracy    - Horizontal accuracy in meters
+ *
+ * Returned Value:
+ *   Status
+ *
+ ****************************************************************************/
+int ubgps_give_location_hint(double const latitude,
+                             double const longitude,
+                             int32_t const altitude,
+                             uint32_t const accuracy);
+
 /****************************************************************************
  * Name: ubgps_setup_poll
  *
diff --git a/apps/system/ubgps/ubgps.c b/apps/system/ubgps/ubgps.c
index fc5332855c9769b8fc500b754bce29c450ce90bc..675d9d34650c12115630279b5f31d4e9c89fe702 100644
--- a/apps/system/ubgps/ubgps.c
+++ b/apps/system/ubgps/ubgps.c
@@ -83,6 +83,10 @@
 
 static struct ubgps_s g_gps;
 
+/* A-GPS hint data structure */
+
+static struct gps_assist_hint_s g_gps_hint;
+
 /* GPS state machine names */
 
 static const char * gps_sm_name[__GPS_STATE_MAX] =
@@ -134,6 +138,7 @@ struct ubgps_s *ubgps_initialize(void)
   /* Clear data */
 
   memset(gps, 0, sizeof(struct ubgps_s));
+  gps->hint = &g_gps_hint;
 
   /* Open GPS serial device */
 
@@ -599,6 +604,8 @@ int ubgps_set_aiding_params(bool const use_time,
 
   dbg_ubgps("\n");
 
+  (void)use_time;
+
   /* Free previously set assistance data */
 
   if (gps->assist)
@@ -614,7 +621,6 @@ int ubgps_set_aiding_params(bool const use_time,
   if (!gps->assist)
     return ERROR;
 
-  gps->assist->use_time = use_time;
   gps->assist->alp_file = NULL;
   gps->assist->alp_file_id = 0;
 
@@ -645,11 +651,88 @@ int ubgps_set_aiding_params(bool const use_time,
     }
 #endif
 
-  gps->assist->use_loc = use_loc;
-  gps->assist->latitude = (uint32_t)(latitude * 10000000.0f);
-  gps->assist->longitude = (uint32_t)(longitude * 10000000.0f);
-  gps->assist->altitude = altitude * 10;
-  gps->assist->accuracy = accuracy * 10;
+  if (use_loc)
+    {
+      if (!g_gps_hint.have_location)
+        {
+          /* Use only if GPS module does not internally already have
+           * location. */
+
+          (void)ubgps_give_location_hint(latitude, longitude, altitude,
+                                         accuracy);
+        }
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: ubgps_give_location_hint
+ *
+ * Description:
+ *   Give location hint for A-GPS
+ *
+ * Input Parameters:
+ *   latitude    - Latitude
+ *   longitude   - Longitude
+ *   altitude    - Altitude in meters
+ *   accuracy    - Horizontal accuracy in meters
+ *
+ * Returned Value:
+ *   Status
+ *
+ ****************************************************************************/
+
+int ubgps_give_location_hint(double const latitude,
+                             double const longitude,
+                             int32_t const altitude,
+                             uint32_t const accuracy)
+{
+  struct timespec currtime = {};
+
+  if (accuracy > HINT_LOCATION_MINIMUM_NEW_ACCURACY)
+    {
+      errno = EINVAL;
+      return ERROR;
+    }
+
+  (void)clock_gettime(CLOCK_MONOTONIC, &currtime);
+
+  if (g_gps_hint.have_location)
+    {
+      uint64_t current_accuracy;
+      uint32_t secs_since = currtime.tv_sec - g_gps_hint.location_time.tv_sec;
+
+      /* Adjust location accuracy by time*speed. */
+
+      current_accuracy = g_gps_hint.accuracy;
+      current_accuracy += ((uint64_t)HINT_LOCATION_ACCURACY_DEGRADE_SPEED_MPS *
+                           secs_since);
+
+      /* Use old location if its accuracy is better than new. Accuracy of
+       * old location data will degrade over time and eventually be overridden
+       * with new location. */
+
+      if (current_accuracy < accuracy)
+        {
+          errno = EALREADY;
+          return ERROR;
+        }
+    }
+
+
+  g_gps_hint.location_time = currtime;
+  g_gps_hint.have_location = true;
+  g_gps_hint.latitude = latitude * 1e7;
+  g_gps_hint.longitude = longitude * 1e7;
+  g_gps_hint.altitude = altitude;
+  g_gps_hint.accuracy = accuracy;
+
+  dbg_ubgps("New location hint:\n");
+  dbg_ubgps(" lat     : %d\n", g_gps_hint.latitude);
+  dbg_ubgps(" long    : %d\n", g_gps_hint.longitude);
+  dbg_ubgps(" alt     : %d meters\n", altitude);
+  dbg_ubgps(" accuracy: %u meters\n", g_gps_hint.accuracy);
 
   return OK;
 }
diff --git a/apps/system/ubgps/ubgps_internal.c b/apps/system/ubgps/ubgps_internal.c
index b95f2721e31a08ff7149daed51e759cbd62add8f..33366a5518aa84e121c4018ed4fef11fd4ae5e82 100644
--- a/apps/system/ubgps/ubgps_internal.c
+++ b/apps/system/ubgps/ubgps_internal.c
@@ -1099,7 +1099,6 @@ int ubgps_send_aid_alp_poll(struct ubgps_s * const gps)
 int ubgps_send_aid_ini(struct ubgps_s * const gps)
 {
   struct ubx_msg_s * msg;
-  time_t currtime;
   struct tm t;
   uint32_t latitude = 0;
   uint32_t longitude = 0;
@@ -1117,13 +1116,10 @@ int ubgps_send_aid_ini(struct ubgps_s * const gps)
   if (ubx_busy(&gps->state.ubx_receiver))
     return ERROR;
 
-  /* Check if assistance data is available */
-
-  if (!gps->assist)
-    return OK;
-
-  if (gps->assist->use_time)
+  if (board_rtc_time_is_set(NULL))
     {
+      time_t currtime;
+
       dbg_int("Using system time for GPS.\n");
 
       /* Construct time and date for GPS */
@@ -1141,24 +1137,52 @@ int ubgps_send_aid_ini(struct ubgps_s * const gps)
       flags |= (1 << 1) | (1 << 10);
     }
 
-  if (gps->assist->alp_file)
+  if (gps->assist && gps->assist->alp_file)
     dbg_int("Using AssistNow Offline data from '%s', file ID %d.\n",
         gps->assist->alp_file, gps->assist->alp_file_id);
 
-  if (gps->assist->use_loc)
+  if (gps->hint && gps->hint->have_location)
     {
-      latitude = gps->assist->latitude;
-      longitude = gps->assist->longitude;
-      altitude = gps->assist->altitude;
-      accuracy = gps->assist->accuracy;
+      struct timespec currtime = {};
+      uint64_t current_accuracy;
+
+      (void)clock_gettime(CLOCK_MONOTONIC, &currtime);
+
+      /* Adjust location accuracy by time*speed. */
+
+      current_accuracy = gps->hint->accuracy;
+      current_accuracy +=
+          ((uint64_t)HINT_LOCATION_ACCURACY_DEGRADE_SPEED_MPS *
+           (currtime.tv_sec - gps->hint->location_time.tv_sec));
 
-      dbg_int("Using last known location (lat: %.7f, long: %.7f).\n",
-          (double)latitude / 10000000.0f,
-          (double)longitude / 10000000.0f);
+      current_accuracy *= 100; /* m => cm */
+      if (current_accuracy > UINT32_MAX)
+        current_accuracy = UINT32_MAX;
+
+      altitude = gps->hint->altitude * 100; /* m => cm */
+      if (altitude > INT32_MAX)
+        altitude = INT32_MAX;
+      else if (altitude < INT32_MIN)
+        altitude = INT32_MIN;
+
+      latitude = gps->hint->latitude;
+      longitude = gps->hint->longitude;
+      accuracy = current_accuracy;
+
+      dbg_int("Using last known position:\n");
+      dbg_int(" lat     : %d\n", gps->hint->latitude);
+      dbg_int(" long    : %d\n", gps->hint->longitude);
+      dbg_int(" alt     : %d meters\n", altitude / 100);
+      dbg_int(" acc_old : %u meters\n", gps->hint->accuracy);
+      dbg_int(" acc_curr: %u meters\n", (uint32_t)current_accuracy / 100);
 
       /* Position is given in lat / long / alt */
 
       flags |= (1 << 5);
+
+      /* Position is valid. */
+
+      flags |= (1 << 0);
     }
 
   /* Allocate and setup AID-INI message */
@@ -1291,6 +1315,13 @@ int ubgps_parse_nav_pvt(struct ubgps_s * const gps, struct ubx_msg_s const * con
                gps->location.ground_speed_accuracy/1000,
                gps->location.heading/100000,
                gps->location.heading_accuracy/100000);
+
+      /* Update location hint for A-GPS. */
+
+      (void)ubgps_give_location_hint((double)gps->location.latitude / 1e7,
+                                     (double)gps->location.longitude / 1e7,
+                                     gps->location.height / 1000,
+                                     gps->location.horizontal_accuracy / 1000);
     }
 
   return OK;
diff --git a/apps/system/ubgps/ubgps_internal.h b/apps/system/ubgps/ubgps_internal.h
index 008aaa9ed8435db07fb0420bafb9e3eb53fcb262..b359992bd2020b61c829852ea470165520193281 100644
--- a/apps/system/ubgps/ubgps_internal.h
+++ b/apps/system/ubgps/ubgps_internal.h
@@ -40,6 +40,7 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
 #include <pthread.h>
+#include <arch/board/board-reset.h>
 
 #include "ubgps_events.h"
 #include "ubx.h"
@@ -52,6 +53,16 @@
 
 #define DEFAULT_NAVIGATION_RATE       1000
 
+/* How fast location hint accuracy degrades over time. */
+
+#define HINT_LOCATION_ACCURACY_DEGRADE_SPEED_KPH 50               /* km/h */
+#define HINT_LOCATION_ACCURACY_DEGRADE_SPEED_MPS \
+  (HINT_LOCATION_ACCURACY_DEGRADE_SPEED_KPH * (1000) / (60 * 60)) /* m/s */
+
+/* Minimum accuracy required for location hint. */
+
+#define HINT_LOCATION_MINIMUM_NEW_ACCURACY      1500              /* meters */
+
 /****************************************************************************
  * Public Types
  ****************************************************************************/
@@ -151,10 +162,6 @@ struct nmea_data_s
 /* GPS assistance data structure */
 
 struct gps_assistance_s {
-  /* Use system time */
-
-  bool use_time;
-
   /* Allocated AlmanacPlus filename for AssistNow Offline */
 
   char * alp_file;
@@ -163,33 +170,41 @@ struct gps_assistance_s {
 
   uint16_t alp_file_id;
 
-  /* Use location */
+  /* Aiding server address */
+
+  struct sockaddr_in alp_srv_addr;
+
+  /* Update time of current aiding data in seconds */
 
-  bool use_loc;
+  time_t update_time;
+};
 
-  /* Latitude */
+/* Additional GPS assistance hint data structure */
 
-  uint32_t latitude;
+struct gps_assist_hint_s {
+  /* Flags */
 
-  /* Longitude */
+  bool have_location;
 
-  uint32_t longitude;
+  /* Longitude in 1e7 scale */
 
-  /* Altitude in centimeters */
+  int32_t longitude;
 
-  int32_t altitude;
+  /* Latitude in 1e7 scale */
+
+  int32_t latitude;
 
-  /* Accuracy in centimeters */
+  /* Horizontal accuracy estimate in mm */
 
   uint32_t accuracy;
 
-  /* Aiding server address */
+  /* Height above mean sea level in mm */
 
-  struct sockaddr_in alp_srv_addr;
+  int32_t altitude;
 
-  /* Update time of current aiding data in seconds */
+  /* Date when location data was valid */
 
-  time_t update_time;
+  struct timespec location_time;
 };
 
 /* GPS module internal structure */
@@ -239,6 +254,7 @@ struct ubgps_s {
   /* GPS assistance data */
 
   struct gps_assistance_s * assist;
+  struct gps_assist_hint_s * hint;
 };
 
 
diff --git a/apps/system/ubgps/ubgps_state.c b/apps/system/ubgps/ubgps_state.c
index 566b126228925962ff06acdc03920f1201af166b..1a95b01e6772d08cacd840b29135b6959eb28971 100644
--- a/apps/system/ubgps/ubgps_state.c
+++ b/apps/system/ubgps/ubgps_state.c
@@ -586,15 +586,6 @@ static int ubgps_sm_global(struct ubgps_s * const gps, struct sm_event_s const *
                   gps->state.psm_timer_id = ts_core_timer_setup_date(&ts,
                       ubgps_psm_timer_cb, gps);
 
-                  /* Update assist params */
-
-                  gps->assist->use_time = true;
-                  gps->assist->use_loc = true;
-                  gps->assist->latitude = gps->location.latitude;
-                  gps->assist->longitude = gps->location.longitude;
-                  gps->assist->altitude = gps->location.height;
-                  gps->assist->accuracy = gps->location.horizontal_accuracy;
-
                   dbg_sm("gps->state.psm_timer_id:%d, set POWER_OFF\n",
                       gps->state.psm_timer_id);
                   ubgps_set_new_state(gps, GPS_STATE_POWER_OFF);