Arena memory allocator
Missing copy constructor &amp; assignment operator
Because you're handling raw pointers and owning memory through them, you must implement the rule of three. Otherwise you will get double deletes after some one copies your allocator.
Use of reset()
By the looks of it, this class is developed for a very specific purpose. OP hasn't told us what the purpose is unfortunately. And the class is kind of dangerous.
Calling reset() will conceptually invalidate any pointers returned by construct(...) but they will continue to be accessible and eventually overwritten with new data until the ArenaAllocator is destroyed. If some piece of code is wrongly holding a pointer to a data block after the reset this should be a bug but static and dynamic code analysis tools will likely not detect this because the pointer is still valid. Neither will you get a crash, just a quiet possibly wrong result.
Although safe if used correctly in a single threaded environment, I'm afraid that it is easy to make a mistake with this class.
Ewww! Raw new/delete
Instead of having a custom allocator policy (BlockProvider) you could use the standard std::allocator for example. By doing this you can now use std::shared_ptr with the allocator provided and get rid of the usage of raw new/delete which is bad, yet you still have the option of providing your own allocator. Don't worry, the overhead of using std::shared_ptr is minimal in this case because your blocks are large.
Overall
I don't see any obvious bugs besides the missing rule of three.
Although custom memory management has its uses, you really do want profiling data to back up the added complexity and failure points of rolling your own memory management. Unless you have a strong reason for custom management that seriously outweighs the reduction in efficacy of code analysis tools and increase in risk for bugs, I would not recommend rolling your own. You have to be sure the extra headache is worth it.
Also note, that if your type is a POD then operator delete will not call any destructors (there aren't any!). In fact I would expect various standard library functions to not call destructors on trivially destructible types any way. Apparently at least GCC does this.
If you have a piece of code that must rapidly allocate and throw away memory at a pace where the standard allocator isn't fast enough, then you might want to consider changing that code to re-use the same memory area instead. This is even faster than writing a custom allocator, solves the problem at the root and doesn't introduce near as much hair loss as custom memory management.
If you just need a lot of fixed size objects quickly and contiguously, I would consider using a fixed item size memory pool and overloaded new/delete for the class and make it transparent. You can do some very efficient reclamation and allocation when items are of fixed size.