diff --git a/libgnome-control-center/cc-panel.c b/libgnome-control-center/cc-panel.c
index 0ed5627..7cc6223 100644
--- a/libgnome-control-center/cc-panel.c
+++ b/libgnome-control-center/cc-panel.c
@@ -221,3 +221,11 @@ cc_panel_get_shell (CcPanel *panel)
   return panel->priv->shell;
 }
 
+gboolean
+cc_panel_class_should_be_visible (CcPanelClass *panel_class)
+{
+  if (panel_class->should_be_visible)
+    return panel_class->should_be_visible ();
+
+  return TRUE;
+}
diff --git a/libgnome-control-center/cc-panel.h b/libgnome-control-center/cc-panel.h
index b1518c8..10b49cd 100644
--- a/libgnome-control-center/cc-panel.h
+++ b/libgnome-control-center/cc-panel.h
@@ -66,12 +66,15 @@ struct _CcPanelClass
 {
   /*< private >*/
   GtkBinClass parent_class;
+
+  gboolean (*should_be_visible) (void);
 };
 
 GType        cc_panel_get_type         (void);
 
 CcShell*     cc_panel_get_shell        (CcPanel     *panel);
 
+gboolean     cc_panel_class_should_be_visible (CcPanelClass *panel_class);
 
 G_END_DECLS
 
diff --git a/shell/cc-shell-model.c b/shell/cc-shell-model.c
index 8f63801..d277702 100644
--- a/shell/cc-shell-model.c
+++ b/shell/cc-shell-model.c
@@ -156,9 +156,11 @@ desktop_entry_has_panel_category (GKeyFile *key_file)
 }
 
 void
-cc_shell_model_add_item (CcShellModel   *model,
-                         const gchar    *category_name,
-                         GMenuTreeEntry *item)
+cc_shell_model_add_item (CcShellModel       *model,
+                         const gchar        *category_name,
+                         GMenuTreeEntry     *item,
+                         CcPanelVisibleFunc  visible_func,
+                         gpointer            data)
 {
   const gchar *icon = gmenu_tree_entry_get_icon (item);
   const gchar *name = gmenu_tree_entry_get_name (item);
@@ -195,6 +197,16 @@ cc_shell_model_add_item (CcShellModel   *model,
       id = g_strdup (gmenu_tree_entry_get_desktop_file_id (item));
     }
 
+  if (visible_func && !visible_func (id, data))
+    {
+      g_debug ("Not loading desktop file '%s' because the panel '%s' "
+               "refuses to be shown.",
+               desktop, id);
+      g_key_file_free (key_file);
+      g_free (id);
+      return;
+    }
+
   keywords = g_key_file_get_locale_string_list (key_file, "Desktop Entry",
                                                 GNOME_SETTINGS_PANEL_ID_KEYWORDS,
                                                 NULL, NULL, NULL);
diff --git a/shell/cc-shell-model.h b/shell/cc-shell-model.h
index 6208e43..50cf92e 100644
--- a/shell/cc-shell-model.h
+++ b/shell/cc-shell-model.h
@@ -81,9 +81,13 @@ GType cc_shell_model_get_type (void) G_GNUC_CONST;
 
 CcShellModel *cc_shell_model_new (void);
 
-void cc_shell_model_add_item (CcShellModel   *model,
-                              const gchar    *category_name,
-                              GMenuTreeEntry *item);
+typedef gboolean (*CcPanelVisibleFunc) (const gchar *id, gpointer data);
+
+void cc_shell_model_add_item (CcShellModel       *model,
+                              const gchar        *category_name,
+                              GMenuTreeEntry     *item,
+                              CcPanelVisibleFunc  visible_func,
+                              gpointer            data);
 
 G_END_DECLS
 
diff --git a/shell/gnome-control-center.c b/shell/gnome-control-center.c
index b577bf0..e5585a9 100644
--- a/shell/gnome-control-center.c
+++ b/shell/gnome-control-center.c
@@ -82,13 +82,9 @@ struct _GnomeControlCenterPrivate
  * for the user than resizing vertically */
 #define FIXED_WIDTH 675
 
-
-static void
-activate_panel (GnomeControlCenter *shell,
-                const gchar        *id,
-                const gchar        *desktop_file,
-                const gchar        *name,
-                const gchar        *icon_name)
+static GType
+get_panel_type (GnomeControlCenter *shell,
+                const gchar        *id)
 {
   GnomeControlCenterPrivate *priv = shell->priv;
   GType panel_type = G_TYPE_INVALID;
@@ -97,9 +93,6 @@ activate_panel (GnomeControlCenter *shell,
   /* check if there is an plugin that implements this panel */
   panels = g_io_extension_point_get_extensions (priv->extension_point);
 
-  if (!desktop_file)
-    return;
-
   if (id)
     {
 
@@ -118,50 +111,62 @@ activate_panel (GnomeControlCenter *shell,
               break;
             }
         }
+    }
 
-      if (panel_type != G_TYPE_INVALID)
-        {
-          GtkWidget *panel;
-          GtkWidget *box;
-          gint i;
-          int nat_height;
+  return panel_type;
+}
 
-          /* create the panel plugin */
-          panel = g_object_new (panel_type, "shell", shell, NULL);
+static void
+activate_panel (GnomeControlCenter *shell,
+                const gchar        *id,
+                const gchar        *desktop_file,
+                const gchar        *name,
+                const gchar        *icon_name)
+{
+  GnomeControlCenterPrivate *priv = shell->priv;
+  GType panel_type = G_TYPE_INVALID;
+  GtkWidget *panel;
+  GtkWidget *box;
+  gint i;
+  int nat_height;
 
-          box = gtk_alignment_new (0, 0, 1, 1);
-          gtk_alignment_set_padding (GTK_ALIGNMENT (box), 6, 6, 6, 6);
+  if (!desktop_file)
+    return;
 
-          gtk_container_add (GTK_CONTAINER (box), panel);
+  panel_type = get_panel_type (shell, id);
 
-          i = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), box,
-                                        NULL);
+  if (panel_type == G_TYPE_INVALID)
+    return;
 
-          /* switch to the new panel */
-          gtk_widget_show (box);
-          gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), i);
+  /* create the panel plugin */
+  panel = g_object_new (panel_type, "shell", shell, NULL);
 
-          /* set the title of the window */
-          gtk_window_set_title (GTK_WINDOW (priv->window), name);
-          gtk_window_set_default_icon_name (icon_name);
-          gtk_window_set_icon_name (GTK_WINDOW (priv->window), icon_name);
+  box = gtk_alignment_new (0, 0, 1, 1);
+  gtk_alignment_set_padding (GTK_ALIGNMENT (box), 6, 6, 6, 6);
 
-          gtk_widget_show (panel);
+  gtk_container_add (GTK_CONTAINER (box), panel);
 
-          /* set the scrolled window small so that it doesn't force
-             the window to be larger than this panel */
-          gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (priv->scrolled_window), 50);
+  i = gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), box, NULL);
 
-          /* resize to the preferred size of the panel */
-          gtk_widget_set_size_request (priv->window, FIXED_WIDTH, -1);
-          gtk_widget_get_preferred_height (GTK_WIDGET (priv->window),
-                                           NULL, &nat_height);
-          gtk_window_resize (GTK_WINDOW (priv->window),
-                             FIXED_WIDTH,
-                             nat_height);
-          return;
-        }
-    }
+  /* switch to the new panel */
+  gtk_widget_show (box);
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), i);
+
+  /* set the title of the window */
+  gtk_window_set_title (GTK_WINDOW (priv->window), name);
+  gtk_window_set_default_icon_name (icon_name);
+  gtk_window_set_icon_name (GTK_WINDOW (priv->window), icon_name);
+
+  gtk_widget_show (panel);
+
+  /* set the scrolled window small so that it doesn't force
+     the window to be larger than this panel */
+  gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (priv->scrolled_window), 50);
+
+  /* resize to the preferred size of the panel */
+  gtk_widget_set_size_request (priv->window, FIXED_WIDTH, -1);
+  gtk_widget_get_preferred_height (GTK_WIDGET (priv->window), NULL, &nat_height);
+  gtk_window_resize (GTK_WINDOW (priv->window), FIXED_WIDTH, nat_height);
 }
 
 static void
@@ -596,6 +601,26 @@ maybe_add_category_view (GnomeControlCenter *shell,
   g_hash_table_insert (shell->priv->category_views, g_strdup (name), categoryview);
 }
 
+static gboolean
+panel_should_be_visible (const gchar *id, gpointer data)
+{
+  GnomeControlCenter *shell = data;
+  GType panel_type;
+  CcPanelClass *panel_class;
+  gboolean result;
+
+  panel_type = get_panel_type (shell, id);
+
+  if (panel_type == G_TYPE_INVALID)
+    return FALSE;
+
+  panel_class = g_type_class_ref (panel_type);
+  result = cc_panel_class_should_be_visible (panel_class);
+  g_type_class_unref (panel_class);
+
+  return result;
+}
+
 static void
 reload_menu (GnomeControlCenter *shell)
 {
@@ -626,8 +651,8 @@ reload_menu (GnomeControlCenter *shell)
               if (gmenu_tree_item_get_type (f->data) == GMENU_TREE_ITEM_ENTRY)
                 {
                   cc_shell_model_add_item (CC_SHELL_MODEL (shell->priv->store),
-                                           dir_name,
-                                           f->data);
+                                           dir_name, f->data,
+                                           panel_should_be_visible, shell);
                 }
             }
 
@@ -1058,12 +1083,12 @@ gnome_control_center_init (GnomeControlCenter *self)
   g_signal_connect (gtk_builder_get_object (priv->builder, "home-button"),
                     "clicked", G_CALLBACK (home_button_clicked_cb), self);
 
-  /* load the available settings panels */
-  setup_model (self);
-
   /* load the panels that are implemented as plugins */
   load_panel_plugins (self);
 
+  /* load the available settings panels */
+  setup_model (self);
+
   /* setup search functionality */
   setup_search (self);
 
