diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index a53b6bd7c..eafe66a08 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1101,7 +1101,11 @@ static inline std::vector<const PrintInstance*> sort_object_instances_by_max_z(c
 }
 
 // Produce a vector of PrintObjects in the order of their respective ModelObjects in print.model().
-static inline std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print &print)
+#if ENABLE_SHOW_SCENE_LABELS
+std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print& print)
+#else
+static inline std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print& print)
+#endif // ENABLE_SHOW_SCENE_LABELS
 {
     // Build up map from ModelInstance* to PrintInstance*
     std::vector<std::pair<const ModelInstance*, const PrintInstance*>> model_instance_to_print_instance;
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 10463277b..e0f16f9fd 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -418,6 +418,10 @@ private:
     friend class WipeTowerIntegration;
 };
 
+#if ENABLE_SHOW_SCENE_LABELS
+std::vector<const PrintInstance*> sort_object_instances_by_model_order(const Print& print);
+#endif // ENABLE_SHOW_SCENE_LABELS
+
 }
 
 #endif
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index 2989b6dde..2c484d554 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -6,6 +6,9 @@
 #include "polypartition.h"
 #include "libslic3r/ClipperUtils.hpp"
 #include "libslic3r/PrintConfig.hpp"
+#if ENABLE_SHOW_SCENE_LABELS
+#include "libslic3r/GCode.hpp"
+#endif // ENABLE_SHOW_SCENE_LABELS
 #include "libslic3r/GCode/PreviewData.hpp"
 #if ENABLE_THUMBNAIL_GENERATOR
 #include "libslic3r/GCode/ThumbnailData.hpp"
@@ -1250,7 +1253,7 @@ bool GLCanvas3D::Labels::is_shown() const
     return wxGetApp().app_config->get("show_labels") == "1";
 }
 
-void GLCanvas3D::Labels::render() const
+void GLCanvas3D::Labels::render(const std::vector<const PrintInstance*>& sorted_instances) const
 {
     if (!m_enabled || !is_shown())
         return;
@@ -1268,47 +1271,59 @@ void GLCanvas3D::Labels::render() const
     {
         int obj_idx;
         int inst_idx;
+        size_t model_instance_id;
         BoundingBoxf3 world_box;
         double eye_center_z;
-        std::string id_str;
-        std::string instance_str;
+        std::string title;
+        std::string label;
+        std::string print_order;
         bool selected;
     };
 
-    // collect world bounding boxes from volumes
+    // collect owners world bounding boxes and data from volumes
     std::vector<Owner> owners;
     const GLVolumeCollection& volumes = m_canvas.get_volumes();
-    for (const GLVolume* volume : volumes.volumes)
-    {
+    for (const GLVolume* volume : volumes.volumes) {
         int obj_idx = volume->object_idx();
-        if ((0 <= obj_idx) && (obj_idx < (int)model->objects.size()))
-        {
+        if (0 <= obj_idx && obj_idx < (int)model->objects.size()) {
             int inst_idx = volume->instance_idx();
             std::vector<Owner>::iterator it = std::find_if(owners.begin(), owners.end(), [obj_idx, inst_idx](const Owner& owner) {
                 return (owner.obj_idx == obj_idx) && (owner.inst_idx == inst_idx);
                 });
-            if (it != owners.end())
-            {
+            if (it != owners.end()) {
                 it->world_box.merge(volume->transformed_bounding_box());
                 it->selected &= volume->selected;
-            }
-            else
-            {
+            } else {
+                const ModelObject* model_object = model->objects[obj_idx];
                 Owner owner;
                 owner.obj_idx = obj_idx;
                 owner.inst_idx = inst_idx;
+                owner.model_instance_id = model_object->instances[inst_idx]->id().id;
                 owner.world_box = volume->transformed_bounding_box();
+                owner.title = "object" + std::to_string(obj_idx) + "_inst##" + std::to_string(inst_idx);
+                owner.label = model_object->name;
+                if (model_object->instances.size() > 1)
+                    owner.label += " (" + std::to_string(inst_idx + 1) + ")";
                 owner.selected = volume->selected;
-                owner.id_str = "object" + std::to_string(obj_idx) + "_inst##" + std::to_string(inst_idx);
-                owner.instance_str = _(L("Instance ")) + std::to_string(inst_idx + 1);
                 owners.push_back(owner);
             }
         }
     }
 
+    // updates print order strings
+    if (sorted_instances.size() > 1) {
+        for (int i = 0; i < sorted_instances.size(); ++i) {
+            size_t id = sorted_instances[i]->model_instance->id().id;
+            std::vector<Owner>::iterator it = std::find_if(owners.begin(), owners.end(), [id](const Owner& owner) {
+                return owner.model_instance_id == id;
+                });
+            if (it != owners.end())
+                it->print_order = _(L("Seq.")) + "#: " + std::to_string(i + 1);
+        }
+    }
+
     // calculate eye bounding boxes center zs
-    for (Owner& owner : owners)
-    {
+    for (Owner& owner : owners) {
         owner.eye_center_z = (world_to_eye * owner.world_box.center())(2);
     }
 
@@ -1325,45 +1340,45 @@ void GLCanvas3D::Labels::render() const
     ImGuiWrapper& imgui = *wxGetApp().imgui();
 
     // render info windows
-    for (const Owner& owner : owners)
-    {
+    for (const Owner& owner : owners) {
         Vec3d screen_box_center = world_to_screen * owner.world_box.center();
         float x = 0.0f;
         float y = 0.0f;
-        if (camera.get_type() == Camera::Perspective)
-        {
+        if (camera.get_type() == Camera::Perspective) {
             x = (0.5f + 0.001f * 0.5f * (float)screen_box_center(0)) * viewport[2];
             y = (0.5f - 0.001f * 0.5f * (float)screen_box_center(1)) * viewport[3];
-        }
-        else
-        {
+        } else {
             x = (0.5f + 0.5f * (float)screen_box_center(0)) * viewport[2];
             y = (0.5f - 0.5f * (float)screen_box_center(1)) * viewport[3];
         }
 
-        if ((x < 0.0f) || (viewport[2] < x) || (y < 0.0f) || (viewport[3] < y))
+        if (x < 0.0f || viewport[2] < x || y < 0.0f || viewport[3] < y)
             continue;
 
         ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, owner.selected ? 3.0f : 1.5f);
         ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
         ImGui::PushStyleColor(ImGuiCol_Border, owner.selected ? ImVec4(0.757f, 0.404f, 0.216f, 1.0f) : ImVec4(0.75f, 0.75f, 0.75f, 1.0f));
         imgui.set_next_window_pos(x, y, ImGuiCond_Always, 0.5f, 0.5f);
-        imgui.begin(owner.id_str, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
+        imgui.begin(owner.title, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
         ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
         float win_w = ImGui::GetWindowWidth();
-        std::string object_str = model->objects[owner.obj_idx]->name;
-        float object_str_len = imgui.calc_text_size(object_str).x;
-        ImGui::SetCursorPosX(0.5f * (win_w - object_str_len));
+        float label_len = imgui.calc_text_size(owner.label).x;
+        ImGui::SetCursorPosX(0.5f * (win_w - label_len));
         ImGui::AlignTextToFramePadding();
-        imgui.text(object_str);
-        float instance_str_len = imgui.calc_text_size(owner.instance_str).x;
-        ImGui::SetCursorPosX(0.5f * (win_w - instance_str_len));
-        ImGui::AlignTextToFramePadding();
-        imgui.text(owner.instance_str);
+        imgui.text(owner.label);
+
+        if (!owner.print_order.empty())
+        {
+            ImGui::Separator();
+            float po_len = imgui.calc_text_size(owner.print_order).x;
+            ImGui::SetCursorPosX(0.5f * (win_w - po_len));
+            ImGui::AlignTextToFramePadding();
+            imgui.text(owner.print_order);
+        }
 
         // force re-render while the windows gets to its final size (it takes several frames)
         float content_w = 1 + ImGui::GetWindowContentRegionWidth();
-        if ((content_w <= object_str_len) || (content_w <= instance_str_len))
+        if (content_w <= label_len)
             m_canvas.request_extra_frame();
 
         imgui.end();
@@ -4904,7 +4919,15 @@ void GLCanvas3D::_render_overlays() const
         m_layers_editing.render_overlay(*this);
 
 #if ENABLE_SHOW_SCENE_LABELS
-    m_labels.render();
+    const ConfigOptionBool* opt = dynamic_cast<const ConfigOptionBool*>(m_config->option("complete_objects"));
+    bool sequential_print = (opt != nullptr) ? m_config->opt_bool("complete_objects") : false;
+    std::vector<const PrintInstance*> sorted_instances;
+    if (sequential_print) {
+        const Print* print = fff_print();
+        if (print != nullptr)
+            sorted_instances = sort_object_instances_by_model_order(*print);
+    }
+    m_labels.render(sorted_instances);
 #endif // ENABLE_SHOW_SCENE_LABELS
 
     glsafe(::glPopMatrix());
diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp
index df9e5f152..24675ee30 100644
--- a/src/slic3r/GUI/GLCanvas3D.hpp
+++ b/src/slic3r/GUI/GLCanvas3D.hpp
@@ -40,6 +40,9 @@ class GCodePreviewData;
 struct ThumbnailData;
 #endif // ENABLE_THUMBNAIL_GENERATOR
 struct SlicingParameters;
+#if ENABLE_SHOW_SCENE_LABELS
+struct PrintInstance;
+#endif // ENABLE_SHOW_SCENE_LABELS
 enum LayerHeightEditActionType : unsigned int;
 
 namespace GUI {
@@ -385,7 +388,7 @@ private:
         void enable(bool enable) { m_enabled = enable; }
         void show(bool show);
         bool is_shown() const;
-        void render() const;
+        void render(const std::vector<const PrintInstance*>& sorted_instances) const;
     };
 #endif // ENABLE_SHOW_SCENE_LABELS