It's hard to give a concrete answer without the actual code but from experience I often found that I could make the database and the UI work transparently for both with and without the new feature.
So I would prepare the database (add a table, column, view, procedure, ...) by ADDING functionality and still supporting the original functionality. (Don't break the current interfaces) If adding one of these duplicates existing items consider providing the current data (structure) through views and procedures (that could be dropped later on) Try to prevent the duplication of data; stick to proper database design.
The UI would get the same treatment: use grids that dynamically show the results based on the type of data that they are given (no hard coded columns), populate menu items and buttons based on the type of the data that is shown; databinding is a very powerful mechanism for this. If adding new UI elements duplicates code/UI definitions, consider introducing abstract parent classes or a more dynamic build-up of the UI through databinding.
At the business layer, create new classes that implement the new feature and are as compatible as possible with the current state. If this new implementation duplicates a lot of code consider lifting the duplicate code in an abstract parent class.
Then, in the logic that defines the implementation for the interfaces (DI Container initialization) test for the feature switch and load the new classes instead of the old ones.
I dislike leaking the switch and the testing thereof everywhere in code. I prefer the switch by abstraction: branch by abstraction by Martin Fowler
This way, removing the switch later on will be not that painful, it will have minimal impact.