diff --git a/django/forms/models.py b/django/forms/models.py
index 41380f2..08bc7dc 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -395,8 +395,26 @@ class BaseModelFormSet(BaseFormSet):
             return len(self.get_queryset())
         return super(BaseModelFormSet, self).initial_form_count()
 
+    def _construct_forms(self, *args, **kwargs):
+        if self.is_bound:
+            self._queryset_dict = dict([(o.pk, o) for o in self.get_queryset()])
+        super(BaseModelFormSet, self)._construct_forms(*args, **kwargs)
+        if self.is_bound:
+            del self._queryset_dict
+
     def _construct_form(self, i, **kwargs):
-        if i < self.initial_form_count():
+        from django.db.models import AutoField, OneToOneField, ForeignKey
+        if self.is_bound and i < self.initial_form_count():
+            pk = self.data["%s-%s" % (self.add_prefix(i), self.model._meta.pk.name)]
+            pk_field = self.model._meta.pk
+            if isinstance(pk, OneToOneField) or isinstance(pk, ForeignKey):
+                qs = pk.rel.to._default_manager.get_query_set()
+            else:
+                qs = self.model._default_manager.get_query_set()
+            field = ModelChoiceField(qs, initial=pk, required=False, widget=HiddenInput)
+            pk = field.clean(pk).pk
+            kwargs['instance'] = self._queryset_dict[pk]
+        elif i < self.initial_form_count():
             kwargs['instance'] = self.get_queryset()[i]
         return super(BaseModelFormSet, self)._construct_form(i, **kwargs)
 
@@ -499,9 +517,9 @@ class BaseModelFormSet(BaseFormSet):
             return ((not pk.editable) or (pk.auto_created or isinstance(pk, AutoField))
                 or (pk.rel and pk.rel.parent_link and pk_is_editable(pk.rel.to._meta.pk)))
         if pk_is_editable(pk):
-            try:
-                pk_value = self.get_queryset()[index].pk
-            except IndexError:
+            if form.is_bound:
+                pk_value = form.instance.pk
+            else:
                 pk_value = None
             if isinstance(pk, OneToOneField) or isinstance(pk, ForeignKey):
                 qs = pk.rel.to._default_manager.get_query_set()
