diff --git a/src/network.c b/src/network.c
index 09099fac..9c197731 100644
--- a/src/network.c
+++ b/src/network.c
@@ -75,6 +75,7 @@ struct network {
 	struct l_ecc_point *sae_pt_20; /* SAE PT for Group 20 */
 	unsigned int agent_request;
 	struct l_queue *bss_list;
+	struct l_queue *old_bss_list;
 	struct l_settings *settings;
 	struct l_queue *secrets;
 	struct l_queue *blacklist; /* temporary blacklist for BSS's */
@@ -1129,12 +1130,97 @@ bool network_update_known_frequencies(struct network *network)
 	return true;
 }
 
+const char *network_bss_get_path(const struct network *network,
+						const struct scan_bss *bss)
+{
+	static char path[256];
+
+	snprintf(path, sizeof(path), "%s/%02x%02x%02x%02x%02x%02x",
+			network->object_path, MAC_STR(bss->addr));
+
+	return path;
+}
+
+static bool network_unregister_bss(void *a, void *user_data)
+{
+	struct scan_bss *bss = a;
+	struct network *network = user_data;
+
+	l_dbus_unregister_object(dbus_get_bus(),
+					network_bss_get_path(network, bss));
+
+	return true;
+}
+
+static bool network_register_bss(struct network *network, struct scan_bss *bss)
+{
+	const char *path = network_bss_get_path(network, bss);
+	struct scan_bss *old;
+
+	/*
+	 * Due to station issuing multiple scan requests we may already have
+	 * this BSS data registered. Remove it from the old_bss_list
+	 */
+	old = l_dbus_object_get_data(dbus_get_bus(), path, IWD_BSS_INTERFACE);
+	if (old == bss)
+		return l_queue_remove(network->old_bss_list, bss);
+	else if (old)
+		return l_dbus_object_set_data(dbus_get_bus(), path,
+						IWD_BSS_INTERFACE, bss);
+
+	if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+						IWD_BSS_INTERFACE, bss))
+		return false;
+
+	if (!l_dbus_object_add_interface(dbus_get_bus(), path,
+					L_DBUS_INTERFACE_PROPERTIES, bss))
+		return false;
+
+	return true;
+}
+
+void network_bss_start_update(struct network *network)
+{
+	network->old_bss_list = network->bss_list;
+	network->bss_list = l_queue_new();
+}
+
+void network_bss_stop_update(struct network *network)
+{
+	const struct l_queue_entry *e;
+
+	/*
+	 * Update has finished, clean up any BSS's from the old list that have
+	 * been registered on DBus.
+	 */
+	for (e = l_queue_get_entries(network->old_bss_list); e; e = e->next) {
+		const struct scan_bss *old = e->data;
+		const struct scan_bss *bss;
+		const char *path = network_bss_get_path(network, old);
+
+		bss = l_dbus_object_get_data(dbus_get_bus(), path,
+						IWD_BSS_INTERFACE);
+		/*
+		 * The lookup matched the user data of an old BSS. This should
+		 * be unregistered from DBus
+		 */
+		if (bss && bss == old)
+			l_dbus_object_remove_interface(dbus_get_bus(), path,
+							IWD_BSS_INTERFACE);
+	}
+
+	l_queue_destroy(network->old_bss_list, NULL);
+	network->old_bss_list = NULL;
+}
+
 bool network_bss_add(struct network *network, struct scan_bss *bss)
 {
 	if (!l_queue_insert(network->bss_list, bss, scan_bss_rank_compare,
 									NULL))
 		return false;
 
+	network_register_bss(network, bss);
+
 	/* Done if BSS is not HS20 or we already have network_info set */
 	if (!bss->hs20_capable)
 		return true;
@@ -1168,6 +1254,8 @@ bool network_bss_update(struct network *network, struct scan_bss *bss)
 
 	l_queue_insert(network->bss_list, bss, scan_bss_rank_compare, NULL);
 
+	network_register_bss(network, bss);
+
 	/* Sync frequency for already known networks */
 	if (network->info) {
 		known_network_add_frequency(network->info, bss->frequency);
@@ -1190,7 +1278,12 @@ void network_bss_list_clear(struct network *network)
 
 struct scan_bss *network_bss_list_pop(struct network *network)
 {
-	return l_queue_pop_head(network->bss_list);
+	struct scan_bss *bss = l_queue_pop_head(network->bss_list);
+
+	if (bss)
+		network_unregister_bss(bss, network);
+
+	return bss;
 }
 
 struct scan_bss *network_bss_find_by_addr(struct network *network,
@@ -1899,6 +1992,9 @@ static void network_unregister(struct network *network, int reason)
 
 void network_remove(struct network *network, int reason)
 {
+	l_queue_foreach_remove(network->bss_list,
+				network_unregister_bss, network);
+
 	if (network->object_path)
 		network_unregister(network, reason);
 
@@ -2155,6 +2251,24 @@ static void setup_network_interface(struct l_dbus_interface *interface)
 				network_property_get_known_network, NULL);
 }
 
+static bool network_bss_property_get_address(struct l_dbus *dbus,
+					struct l_dbus_message *message,
+					struct l_dbus_message_builder *builder,
+					void *user_data)
+{
+	struct scan_bss *bss = user_data;
+
+	l_dbus_message_builder_append_basic(builder, 's',
+					util_address_to_string(bss->addr));
+	return true;
+}
+
+static void setup_bss_interface(struct l_dbus_interface *interface)
+{
+	l_dbus_interface_property(interface, "Address", 0, "s",
+					network_bss_property_get_address, NULL);
+}
+
 static int network_init(void)
 {
 	if (!l_dbus_register_interface(dbus_get_bus(), IWD_NETWORK_INTERFACE,
@@ -2162,6 +2276,11 @@ static int network_init(void)
 		l_error("Unable to register %s interface",
 						IWD_NETWORK_INTERFACE);
 
+	if (!l_dbus_register_interface(dbus_get_bus(), IWD_BSS_INTERFACE,
+					setup_bss_interface, NULL, false))
+		l_error("Unable to register %s interface",
+						IWD_BSS_INTERFACE);
+
 	known_networks_watch =
 		known_networks_watch_add(known_networks_changed, NULL, NULL);
 
@@ -2179,6 +2298,7 @@ static void network_exit(void)
 	event_watch = 0;
 
 	l_dbus_unregister_interface(dbus_get_bus(), IWD_NETWORK_INTERFACE);
+	l_dbus_unregister_interface(dbus_get_bus(), IWD_BSS_INTERFACE);
 }
 
 IWD_MODULE(network, network_init, network_exit)
diff --git a/src/network.h b/src/network.h
index 17dfcca8..f27329a9 100644
--- a/src/network.h
+++ b/src/network.h
@@ -67,8 +67,12 @@ int network_can_connect_bss(struct network *network,
 						const struct scan_bss *bss);
 int network_autoconnect(struct network *network, struct scan_bss *bss);
 void network_connect_failed(struct network *network, bool in_handshake);
+void network_bss_start_update(struct network *network);
+void network_bss_stop_update(struct network *network);
 bool network_bss_add(struct network *network, struct scan_bss *bss);
 bool network_bss_update(struct network *network, struct scan_bss *bss);
+const char *network_bss_get_path(const struct network *network,
+						const struct scan_bss *bss);
 bool network_bss_list_isempty(struct network *network);
 void network_bss_list_clear(struct network *network);
 struct scan_bss *network_bss_list_pop(struct network *network);
