diff --git a/theories/tactics.v b/theories/tactics.v
index 746fec70c3a12af9363b1ce8f30e92ff4441531f..ce5368777140d4ef56299904c7c41a05dd0c1e92 100644
--- a/theories/tactics.v
+++ b/theories/tactics.v
@@ -228,7 +228,6 @@ Ltac setoid_subst :=
   | H : @equiv ?A ?e _ ?x |- _ => symmetry in H; setoid_subst_aux (@equiv A e) x
   end.
 
-
 (** f_equiv solves goals of the form "f _ = f _", for any relation and any
     number of arguments, by looking for appropriate "Proper" instances.
     If it cannot solve an equality, it will leave that to the user. *)
@@ -306,6 +305,13 @@ Ltac solve_proper :=
   end;
   solve [ f_equiv ].
 
+(** The tactic [intros_revert tac] introduces all foralls/arrows, performs tac,
+and then reverts them. *)
+Ltac intros_revert tac :=
+  lazymatch goal with
+  | |- ∀ _, _ => let H := fresh in intro H; intros_revert tac; revert H
+  | |- _ => tac
+  end.
 
 (** Given a tactic [tac2] generating a list of terms, [iter tac1 tac2]
 runs [tac x] for each element [x] until [tac x] succeeds. If it does not